From 57da90eedde5b6333a2fd3bba43e55ba8312daf8 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Sat, 24 Feb 2024 21:16:09 +0100 Subject: [PATCH 001/279] tidy: support `ignore-tidy` for Markdown files To be used to skip the `tab` check in `jobserver.md`. Signed-off-by: Miguel Ojeda --- src/tools/tidy/src/style.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 28d70b4454ce..58388938a823 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -178,6 +178,7 @@ fn contains_ignore_directive(can_contain: bool, contents: &str, check: &str) -> if contents.contains(&format!("// ignore-tidy-{check}")) || contents.contains(&format!("# ignore-tidy-{check}")) || contents.contains(&format!("/* ignore-tidy-{check} */")) + || contents.contains(&format!("")) { Directive::Ignore(false) } else { @@ -305,7 +306,8 @@ pub fn check(path: &Path, bad: &mut bool) { let can_contain = contents.contains("// ignore-tidy-") || contents.contains("# ignore-tidy-") - || contents.contains("/* ignore-tidy-"); + || contents.contains("/* ignore-tidy-") + || contents.contains(" tests/ui/single_char_pattern.rs:13:13 - | -LL | x.split("ß"); - | ^^^ help: consider using a `char`: `'ß'` - -error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:14:13 - | -LL | x.split("ℝ"); - | ^^^ help: consider using a `char`: `'ℝ'` - -error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:15:13 - | -LL | x.split("💣"); - | ^^^^ help: consider using a `char`: `'💣'` - error: single-character string constant used as pattern --> tests/ui/single_char_pattern.rs:18:23 | @@ -140,106 +122,94 @@ LL | x.trim_end_matches("x"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:37:20 - | -LL | x.strip_prefix("x"); - | ^^^ help: consider using a `char`: `'x'` - -error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:38:20 - | -LL | x.strip_suffix("x"); - | ^^^ help: consider using a `char`: `'x'` - -error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:39:15 + --> tests/ui/single_char_pattern.rs:37:15 | LL | x.replace("x", "y"); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:40:16 + --> tests/ui/single_char_pattern.rs:38:16 | LL | x.replacen("x", "y", 3); | ^^^ help: consider using a `char`: `'x'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:42:13 + --> tests/ui/single_char_pattern.rs:40:13 | LL | x.split("\n"); | ^^^^ help: consider using a `char`: `'\n'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:43:13 + --> tests/ui/single_char_pattern.rs:41:13 | LL | x.split("'"); | ^^^ help: consider using a `char`: `'\''` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:44:13 + --> tests/ui/single_char_pattern.rs:42:13 | LL | x.split("\'"); | ^^^^ help: consider using a `char`: `'\''` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:46:13 + --> tests/ui/single_char_pattern.rs:44:13 | LL | x.split("\""); | ^^^^ help: consider using a `char`: `'"'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:51:31 + --> tests/ui/single_char_pattern.rs:49:31 | LL | x.replace(';', ",").split(","); // issue #2978 | ^^^ help: consider using a `char`: `','` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:52:19 + --> tests/ui/single_char_pattern.rs:50:19 | LL | x.starts_with("\x03"); // issue #2996 | ^^^^^^ help: consider using a `char`: `'\x03'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:59:13 + --> tests/ui/single_char_pattern.rs:57:13 | LL | x.split(r"a"); | ^^^^ help: consider using a `char`: `'a'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:60:13 + --> tests/ui/single_char_pattern.rs:58:13 | LL | x.split(r#"a"#); | ^^^^^^ help: consider using a `char`: `'a'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:61:13 + --> tests/ui/single_char_pattern.rs:59:13 | LL | x.split(r###"a"###); | ^^^^^^^^^^ help: consider using a `char`: `'a'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:62:13 + --> tests/ui/single_char_pattern.rs:60:13 | LL | x.split(r###"'"###); | ^^^^^^^^^^ help: consider using a `char`: `'\''` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:63:13 + --> tests/ui/single_char_pattern.rs:61:13 | LL | x.split(r###"#"###); | ^^^^^^^^^^ help: consider using a `char`: `'#'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:65:13 + --> tests/ui/single_char_pattern.rs:63:13 | LL | x.split(r#"\"#); | ^^^^^^ help: consider using a `char`: `'\\'` error: single-character string constant used as pattern - --> tests/ui/single_char_pattern.rs:66:13 + --> tests/ui/single_char_pattern.rs:64:13 | LL | x.split(r"\"); | ^^^^ help: consider using a `char`: `'\\'` -error: aborting due to 40 previous errors +error: aborting due to 35 previous errors From 666e2f286854cc3a4dbdb3cc8c934f986765c72b Mon Sep 17 00:00:00 2001 From: J-ZhengLi Date: Wed, 10 Apr 2024 15:53:36 +0800 Subject: [PATCH 007/279] fix [`large_stack_arrays`] linting in `vec` macro & add `matching_root_macro_call` function in `clippy_utils` --- clippy_lints/src/format_args.rs | 6 +-- clippy_lints/src/large_stack_arrays.rs | 25 +++++++++---- clippy_lints/src/manual_assert.rs | 5 +-- clippy_lints/src/manual_is_ascii_check.rs | 15 +------- clippy_lints/src/methods/filter_map.rs | 5 +-- clippy_lints/src/repeat_vec_with_capacity.rs | 5 +-- .../src/slow_vector_initialization.rs | 6 +-- clippy_utils/src/macros.rs | 10 +++++ tests/ui/large_stack_arrays.rs | 34 +++++++++++++++++ tests/ui/large_stack_arrays.stderr | 37 ++++++++++++++++++- 10 files changed, 110 insertions(+), 38 deletions(-) diff --git a/clippy_lints/src/format_args.rs b/clippy_lints/src/format_args.rs index 80db617c639a..003a9995c15f 100644 --- a/clippy_lints/src/format_args.rs +++ b/clippy_lints/src/format_args.rs @@ -4,7 +4,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::is_diag_trait_item; use clippy_utils::macros::{ find_format_arg_expr, find_format_args, format_arg_removal_span, format_placeholder_format_span, is_assert_macro, - is_format_macro, is_panic, root_macro_call, root_macro_call_first_node, FormatParamUsage, MacroCall, + is_format_macro, is_panic, matching_root_macro_call, root_macro_call_first_node, FormatParamUsage, MacroCall, }; use clippy_utils::source::snippet_opt; use clippy_utils::ty::{implements_trait, is_type_lang_item}; @@ -271,9 +271,7 @@ impl<'a, 'tcx> FormatArgsExpr<'a, 'tcx> { let mut suggest_format = |spec| { let message = format!("for the {spec} to apply consider using `format!()`"); - if let Some(mac_call) = root_macro_call(arg_span) - && self.cx.tcx.is_diagnostic_item(sym::format_args_macro, mac_call.def_id) - { + if let Some(mac_call) = matching_root_macro_call(self.cx, arg_span, sym::format_args_macro) { diag.span_suggestion( self.cx.sess().source_map().span_until_char(mac_call.span, '!'), message, diff --git a/clippy_lints/src/large_stack_arrays.rs b/clippy_lints/src/large_stack_arrays.rs index afcb67459476..9214e870e928 100644 --- a/clippy_lints/src/large_stack_arrays.rs +++ b/clippy_lints/src/large_stack_arrays.rs @@ -1,10 +1,12 @@ -use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::macros::macro_backtrace; use clippy_utils::source::snippet; use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, ConstKind}; use rustc_session::impl_lint_pass; +use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does @@ -39,6 +41,7 @@ impl_lint_pass!(LargeStackArrays => [LARGE_STACK_ARRAYS]); impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { if let ExprKind::Repeat(_, _) | ExprKind::Array(_) = expr.kind + && !is_from_vec_macro(cx, expr.span) && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind() && let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind() && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx) @@ -54,7 +57,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { }) && self.maximum_allowed_size < u128::from(element_count) * u128::from(element_size) { - span_lint_and_help( + span_lint_and_then( cx, LARGE_STACK_ARRAYS, expr.span, @@ -62,12 +65,20 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { "allocating a local array larger than {} bytes", self.maximum_allowed_size ), - None, - format!( - "consider allocating on the heap with `vec!{}.into_boxed_slice()`", - snippet(cx, expr.span, "[...]") - ), + |diag| { + if !expr.span.from_expansion() { + diag.help(format!( + "consider allocating on the heap with `vec!{}.into_boxed_slice()`", + snippet(cx, expr.span, "[...]") + )); + } + }, ); } } } + +/// We shouldn't lint messages if the expr is already in a `vec!` call +fn is_from_vec_macro(cx: &LateContext<'_>, expr_span: Span) -> bool { + macro_backtrace(expr_span).any(|mac| cx.tcx.is_diagnostic_item(sym::vec_macro, mac.def_id)) +} diff --git a/clippy_lints/src/manual_assert.rs b/clippy_lints/src/manual_assert.rs index 76edbe8b755b..d76b94eba23e 100644 --- a/clippy_lints/src/manual_assert.rs +++ b/clippy_lints/src/manual_assert.rs @@ -1,12 +1,11 @@ use crate::rustc_lint::LintContext; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::macros::root_macro_call; +use clippy_utils::macros::{is_panic, root_macro_call}; use clippy_utils::{is_else_clause, is_parent_stmt, peel_blocks_with_stmt, span_extract_comment, sugg}; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; -use rustc_span::sym; declare_clippy_lint! { /// ### What it does @@ -42,7 +41,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAssert { && !expr.span.from_expansion() && let then = peel_blocks_with_stmt(then) && let Some(macro_call) = root_macro_call(then.span) - && cx.tcx.item_name(macro_call.def_id) == sym::panic + && is_panic(cx, macro_call.def_id) && !cx.tcx.sess.source_map().is_multiline(cond.span) && let Ok(panic_snippet) = cx.sess().source_map().span_to_snippet(macro_call.span) && let Some(panic_snippet) = panic_snippet.strip_suffix(')') diff --git a/clippy_lints/src/manual_is_ascii_check.rs b/clippy_lints/src/manual_is_ascii_check.rs index 338a299740a8..ed7eabd9b994 100644 --- a/clippy_lints/src/manual_is_ascii_check.rs +++ b/clippy_lints/src/manual_is_ascii_check.rs @@ -1,6 +1,6 @@ use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::macros::root_macro_call; +use clippy_utils::macros::matching_root_macro_call; use clippy_utils::sugg::Sugg; use clippy_utils::{higher, in_constant}; use rustc_ast::ast::RangeLimits; @@ -9,7 +9,6 @@ use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, PatKind, RangeEnd}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; -use rustc_span::def_id::DefId; use rustc_span::{sym, Span}; declare_clippy_lint! { @@ -97,9 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck { return; } - if let Some(macro_call) = root_macro_call(expr.span) - && is_matches_macro(cx, macro_call.def_id) - { + if let Some(macro_call) = matching_root_macro_call(cx, expr.span, sym::matches_macro) { if let ExprKind::Match(recv, [arm, ..], _) = expr.kind { let range = check_pat(&arm.pat.kind); check_is_ascii(cx, macro_call.span, recv, &range); @@ -187,11 +184,3 @@ fn check_range(start: &Expr<'_>, end: &Expr<'_>) -> CharRange { CharRange::Otherwise } } - -fn is_matches_macro(cx: &LateContext<'_>, macro_def_id: DefId) -> bool { - if let Some(name) = cx.tcx.get_diagnostic_name(macro_def_id) { - return sym::matches_macro == name; - } - - false -} diff --git a/clippy_lints/src/methods/filter_map.rs b/clippy_lints/src/methods/filter_map.rs index 581e3b308c3c..02a11257007a 100644 --- a/clippy_lints/src/methods/filter_map.rs +++ b/clippy_lints/src/methods/filter_map.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; -use clippy_utils::macros::{is_panic, root_macro_call}; +use clippy_utils::macros::{is_panic, matching_root_macro_call, root_macro_call}; use clippy_utils::source::{indent_of, reindent_multiline, snippet}; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::{higher, is_trait_method, path_to_local_id, peel_blocks, SpanlessEq}; @@ -247,8 +247,7 @@ impl<'tcx> OffendingFilterExpr<'tcx> { } else { None } - } else if let Some(macro_call) = root_macro_call(expr.span) - && cx.tcx.get_diagnostic_name(macro_call.def_id) == Some(sym::matches_macro) + } else if matching_root_macro_call(cx, expr.span, sym::matches_macro).is_some() // we know for a fact that the wildcard pattern is the second arm && let ExprKind::Match(scrutinee, [arm, _], _) = expr.kind && path_to_local_id(scrutinee, filter_param_id) diff --git a/clippy_lints/src/repeat_vec_with_capacity.rs b/clippy_lints/src/repeat_vec_with_capacity.rs index a358881bf80e..792d8fc88f0b 100644 --- a/clippy_lints/src/repeat_vec_with_capacity.rs +++ b/clippy_lints/src/repeat_vec_with_capacity.rs @@ -1,7 +1,7 @@ use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::VecArgs; -use clippy_utils::macros::root_macro_call; +use clippy_utils::macros::matching_root_macro_call; use clippy_utils::source::snippet; use clippy_utils::{expr_or_init, fn_def_id, match_def_path, paths}; use rustc_errors::Applicability; @@ -65,8 +65,7 @@ fn emit_lint(cx: &LateContext<'_>, span: Span, kind: &str, note: &'static str, s /// Checks `vec![Vec::with_capacity(x); n]` fn check_vec_macro(cx: &LateContext<'_>, expr: &Expr<'_>) { - if let Some(mac_call) = root_macro_call(expr.span) - && cx.tcx.is_diagnostic_item(sym::vec_macro, mac_call.def_id) + if matching_root_macro_call(cx, expr.span, sym::vec_macro).is_some() && let Some(VecArgs::Repeat(repeat_expr, len_expr)) = VecArgs::hir(cx, expr) && fn_def_id(cx, repeat_expr).is_some_and(|did| match_def_path(cx, did, &paths::VEC_WITH_CAPACITY)) && !len_expr.span.from_expansion() diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs index 8a9f02b6dcb1..8a01f9d3e0ab 100644 --- a/clippy_lints/src/slow_vector_initialization.rs +++ b/clippy_lints/src/slow_vector_initialization.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::macros::root_macro_call; +use clippy_utils::macros::matching_root_macro_call; use clippy_utils::sugg::Sugg; use clippy_utils::{ get_enclosing_block, is_expr_path_def_path, is_integer_literal, is_path_diagnostic_item, path_to_local, @@ -145,9 +145,7 @@ impl SlowVectorInit { // Generally don't warn if the vec initializer comes from an expansion, except for the vec! macro. // This lets us still warn on `vec![]`, while ignoring other kinds of macros that may output an // empty vec - if expr.span.from_expansion() - && root_macro_call(expr.span).map(|m| m.def_id) != cx.tcx.get_diagnostic_item(sym::vec_macro) - { + if expr.span.from_expansion() && matching_root_macro_call(cx, expr.span, sym::vec_macro).is_none() { return None; } diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs index f166087dc3ca..257dd76ab15c 100644 --- a/clippy_utils/src/macros.rs +++ b/clippy_utils/src/macros.rs @@ -119,10 +119,20 @@ pub fn macro_backtrace(span: Span) -> impl Iterator { /// If the macro backtrace of `span` has a macro call at the root expansion /// (i.e. not a nested macro call), returns `Some` with the `MacroCall` +/// +/// If you only want to check whether the root macro has a specific name, +/// consider using [`matching_root_macro_call`] instead. pub fn root_macro_call(span: Span) -> Option { macro_backtrace(span).last() } +/// A combination of [`root_macro_call`] and +/// [`is_diagnostic_item`](rustc_middle::ty::TyCtxt::is_diagnostic_item) that returns a `MacroCall` +/// at the root expansion if only it matches the given name. +pub fn matching_root_macro_call(cx: &LateContext<'_>, span: Span, name: Symbol) -> Option { + root_macro_call(span).filter(|mc| cx.tcx.is_diagnostic_item(name, mc.def_id)) +} + /// Like [`root_macro_call`], but only returns `Some` if `node` is the "first node" /// produced by the macro call, as in [`first_node_in_macro`]. pub fn root_macro_call_first_node(cx: &LateContext<'_>, node: &impl HirNode) -> Option { diff --git a/tests/ui/large_stack_arrays.rs b/tests/ui/large_stack_arrays.rs index d5c4f95f8c42..f41423962a19 100644 --- a/tests/ui/large_stack_arrays.rs +++ b/tests/ui/large_stack_arrays.rs @@ -55,3 +55,37 @@ fn main() { [(); 20_000_000], ); } + +#[allow(clippy::useless_vec)] +fn issue_12586() { + macro_rules! dummy { + ($n:expr) => { + $n + }; + // Weird rule to test help messages. + ($a:expr => $b:expr) => { + [$a, $b, $a, $b] + //~^ ERROR: allocating a local array larger than 512000 bytes + }; + ($id:ident; $n:literal) => { + dummy!(::std::vec![$id;$n]) + }; + ($($id:expr),+ $(,)?) => { + ::std::vec![$($id),*] + } + } + + let x = [0u32; 50_000]; + let y = vec![x, x, x, x, x]; + let y = vec![dummy![x, x, x, x, x]]; + let y = vec![dummy![[x, x, x, x, x]]]; + //~^ ERROR: allocating a local array larger than 512000 bytes + let y = dummy![x, x, x, x, x]; + let y = [x, x, dummy!(x), x, x]; + //~^ ERROR: allocating a local array larger than 512000 bytes + let y = dummy![x => x]; + let y = dummy![x;5]; + let y = dummy!(vec![dummy![x, x, x, x, x]]); + let y = dummy![[x, x, x, x, x]]; + //~^ ERROR: allocating a local array larger than 512000 bytes +} diff --git a/tests/ui/large_stack_arrays.stderr b/tests/ui/large_stack_arrays.stderr index 007ca61c2de1..ac4097a463f6 100644 --- a/tests/ui/large_stack_arrays.stderr +++ b/tests/ui/large_stack_arrays.stderr @@ -56,5 +56,40 @@ LL | [0u8; usize::MAX], | = help: consider allocating on the heap with `vec![0u8; usize::MAX].into_boxed_slice()` -error: aborting due to 7 previous errors +error: allocating a local array larger than 512000 bytes + --> tests/ui/large_stack_arrays.rs:81:25 + | +LL | let y = vec![dummy![[x, x, x, x, x]]]; + | ^^^^^^^^^^^^^^^ + | + = help: consider allocating on the heap with `vec![x, x, x, x, x].into_boxed_slice()` + +error: allocating a local array larger than 512000 bytes + --> tests/ui/large_stack_arrays.rs:84:13 + | +LL | let y = [x, x, dummy!(x), x, x]; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider allocating on the heap with `vec![x, x, dummy!(x), x, x].into_boxed_slice()` + +error: allocating a local array larger than 512000 bytes + --> tests/ui/large_stack_arrays.rs:67:13 + | +LL | [$a, $b, $a, $b] + | ^^^^^^^^^^^^^^^^ +... +LL | let y = dummy![x => x]; + | -------------- in this macro invocation + | + = note: this error originates in the macro `dummy` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: allocating a local array larger than 512000 bytes + --> tests/ui/large_stack_arrays.rs:89:20 + | +LL | let y = dummy![[x, x, x, x, x]]; + | ^^^^^^^^^^^^^^^ + | + = help: consider allocating on the heap with `vec![x, x, x, x, x].into_boxed_slice()` + +error: aborting due to 11 previous errors From 2861729dadfb7a3567840314311fee86e54299a2 Mon Sep 17 00:00:00 2001 From: J-ZhengLi Date: Wed, 17 Apr 2024 18:10:50 +0800 Subject: [PATCH 008/279] test [`large_stack_arrays`] with proc-macro and make sure not to offer false help messages if in one. --- clippy_lints/src/large_stack_arrays.rs | 50 +++++++++++++++++++++----- tests/ui/auxiliary/proc_macros.rs | 17 +++++++++ tests/ui/large_stack_arrays.rs | 16 ++++++++- tests/ui/large_stack_arrays.stderr | 47 ++++++++++++++---------- 4 files changed, 102 insertions(+), 28 deletions(-) diff --git a/clippy_lints/src/large_stack_arrays.rs b/clippy_lints/src/large_stack_arrays.rs index 9214e870e928..208d1bb6e68a 100644 --- a/clippy_lints/src/large_stack_arrays.rs +++ b/clippy_lints/src/large_stack_arrays.rs @@ -1,7 +1,8 @@ use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::is_from_proc_macro; use clippy_utils::macros::macro_backtrace; use clippy_utils::source::snippet; -use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node}; +use rustc_hir::{ArrayLen, Expr, ExprKind, Item, ItemKind, Node}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, ConstKind}; @@ -27,21 +28,41 @@ declare_clippy_lint! { pub struct LargeStackArrays { maximum_allowed_size: u128, + prev_vec_macro_callsite: Option, } impl LargeStackArrays { #[must_use] pub fn new(maximum_allowed_size: u128) -> Self { - Self { maximum_allowed_size } + Self { + maximum_allowed_size, + prev_vec_macro_callsite: None, + } + } + + /// Check if the given span of an expr is already in a `vec!` call. + fn is_from_vec_macro(&mut self, cx: &LateContext<'_>, span: Span) -> bool { + // First, we check if this is span is within the last encountered `vec!` macro's root callsite. + self.prev_vec_macro_callsite + .is_some_and(|vec_mac| vec_mac.contains(span)) + || { + // Then, we try backtracking the macro expansions, to see if there's a `vec!` macro, + // and update the `prev_vec_macro_callsite`. + let res = macro_backtrace(span).any(|mac| cx.tcx.is_diagnostic_item(sym::vec_macro, mac.def_id)); + if res { + self.prev_vec_macro_callsite = Some(span.source_callsite()); + } + res + } } } impl_lint_pass!(LargeStackArrays => [LARGE_STACK_ARRAYS]); impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { - fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { if let ExprKind::Repeat(_, _) | ExprKind::Array(_) = expr.kind - && !is_from_vec_macro(cx, expr.span) + && !self.is_from_vec_macro(cx, expr.span) && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind() && let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind() && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx) @@ -66,7 +87,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { self.maximum_allowed_size ), |diag| { - if !expr.span.from_expansion() { + if !might_be_expanded(cx, expr) { diag.help(format!( "consider allocating on the heap with `vec!{}.into_boxed_slice()`", snippet(cx, expr.span, "[...]") @@ -78,7 +99,20 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { } } -/// We shouldn't lint messages if the expr is already in a `vec!` call -fn is_from_vec_macro(cx: &LateContext<'_>, expr_span: Span) -> bool { - macro_backtrace(expr_span).any(|mac| cx.tcx.is_diagnostic_item(sym::vec_macro, mac.def_id)) +/// Only giving help messages if the expr does not contains macro expanded codes. +fn might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool { + /// Check if the span of `ArrayLen` of a repeat expression is within the expr's span, + /// if not, meaning this repeat expr is definitely from some proc-macro. + /// + /// This is a fail-safe to a case where even the `is_from_proc_macro` is unable to determain the + /// correct result. + fn repeat_expr_might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool { + let ExprKind::Repeat(_, ArrayLen::Body(anon_const)) = expr.kind else { + return false; + }; + let len_span = cx.tcx.def_span(anon_const.def_id); + !expr.span.contains(len_span) + } + + expr.span.from_expansion() || is_from_proc_macro(cx, expr) || repeat_expr_might_be_expanded(cx, expr) } diff --git a/tests/ui/auxiliary/proc_macros.rs b/tests/ui/auxiliary/proc_macros.rs index 3303eb145678..6e6919cd295c 100644 --- a/tests/ui/auxiliary/proc_macros.rs +++ b/tests/ui/auxiliary/proc_macros.rs @@ -9,6 +9,7 @@ use proc_macro::token_stream::IntoIter; use proc_macro::Delimiter::{self, Brace, Parenthesis}; use proc_macro::Spacing::{self, Alone, Joint}; use proc_macro::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree as TT}; +use syn::spanned::Spanned; type Result = core::result::Result; @@ -124,6 +125,22 @@ fn write_with_span(s: Span, mut input: IntoIter, out: &mut TokenStream) -> Resul Ok(()) } +/// Takes an array repeat expression such as `[0_u32; 2]`, and return the tokens with 10 times the +/// original size, which turns to `[0_u32; 20]`. +#[proc_macro] +pub fn make_it_big(input: TokenStream) -> TokenStream { + let mut expr_repeat = syn::parse_macro_input!(input as syn::ExprRepeat); + let len_span = expr_repeat.len.span(); + if let syn::Expr::Lit(expr_lit) = &mut *expr_repeat.len { + if let syn::Lit::Int(lit_int) = &expr_lit.lit { + let orig_val = lit_int.base10_parse::().expect("not a valid length parameter"); + let new_val = orig_val.saturating_mul(10); + expr_lit.lit = syn::parse_quote_spanned!( len_span => #new_val); + } + } + quote::quote!(#expr_repeat).into() +} + /// Within the item this attribute is attached to, an `inline!` macro is available which expands the /// contained tokens as though they came from a macro expansion. /// diff --git a/tests/ui/large_stack_arrays.rs b/tests/ui/large_stack_arrays.rs index f41423962a19..6bcaf481c9f7 100644 --- a/tests/ui/large_stack_arrays.rs +++ b/tests/ui/large_stack_arrays.rs @@ -1,6 +1,9 @@ +//@aux-build:proc_macros.rs #![warn(clippy::large_stack_arrays)] #![allow(clippy::large_enum_variant)] +extern crate proc_macros; + #[derive(Clone, Copy)] struct S { pub data: [u64; 32], @@ -74,12 +77,18 @@ fn issue_12586() { ::std::vec![$($id),*] } } + macro_rules! create_then_move { + ($id:ident; $n:literal) => {{ + let _x_ = [$id; $n]; + //~^ ERROR: allocating a local array larger than 512000 bytes + _x_ + }}; + } let x = [0u32; 50_000]; let y = vec![x, x, x, x, x]; let y = vec![dummy![x, x, x, x, x]]; let y = vec![dummy![[x, x, x, x, x]]]; - //~^ ERROR: allocating a local array larger than 512000 bytes let y = dummy![x, x, x, x, x]; let y = [x, x, dummy!(x), x, x]; //~^ ERROR: allocating a local array larger than 512000 bytes @@ -88,4 +97,9 @@ fn issue_12586() { let y = dummy!(vec![dummy![x, x, x, x, x]]); let y = dummy![[x, x, x, x, x]]; //~^ ERROR: allocating a local array larger than 512000 bytes + + let y = proc_macros::make_it_big!([x; 1]); + //~^ ERROR: allocating a local array larger than 512000 bytes + let y = vec![proc_macros::make_it_big!([x; 10])]; + let y = vec![create_then_move![x; 5]; 5]; } diff --git a/tests/ui/large_stack_arrays.stderr b/tests/ui/large_stack_arrays.stderr index ac4097a463f6..06294ee8b8cb 100644 --- a/tests/ui/large_stack_arrays.stderr +++ b/tests/ui/large_stack_arrays.stderr @@ -1,5 +1,5 @@ error: allocating a local array larger than 512000 bytes - --> tests/ui/large_stack_arrays.rs:29:14 + --> tests/ui/large_stack_arrays.rs:32:14 | LL | let _x = [build(); 3]; | ^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | let _x = [build(); 3]; = help: to override `-D warnings` add `#[allow(clippy::large_stack_arrays)]` error: allocating a local array larger than 512000 bytes - --> tests/ui/large_stack_arrays.rs:32:14 + --> tests/ui/large_stack_arrays.rs:35:14 | LL | let _y = [build(), build(), build()]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let _y = [build(), build(), build()]; = help: consider allocating on the heap with `vec![build(), build(), build()].into_boxed_slice()` error: allocating a local array larger than 512000 bytes - --> tests/ui/large_stack_arrays.rs:38:9 + --> tests/ui/large_stack_arrays.rs:41:9 | LL | [0u32; 20_000_000], | ^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | [0u32; 20_000_000], = help: consider allocating on the heap with `vec![0u32; 20_000_000].into_boxed_slice()` error: allocating a local array larger than 512000 bytes - --> tests/ui/large_stack_arrays.rs:40:9 + --> tests/ui/large_stack_arrays.rs:43:9 | LL | [S { data: [0; 32] }; 5000], | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | [S { data: [0; 32] }; 5000], = help: consider allocating on the heap with `vec![S { data: [0; 32] }; 5000].into_boxed_slice()` error: allocating a local array larger than 512000 bytes - --> tests/ui/large_stack_arrays.rs:42:9 + --> tests/ui/large_stack_arrays.rs:45:9 | LL | [Some(""); 20_000_000], | ^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | [Some(""); 20_000_000], = help: consider allocating on the heap with `vec![Some(""); 20_000_000].into_boxed_slice()` error: allocating a local array larger than 512000 bytes - --> tests/ui/large_stack_arrays.rs:44:9 + --> tests/ui/large_stack_arrays.rs:47:9 | LL | [E::T(0); 5000], | ^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | [E::T(0); 5000], = help: consider allocating on the heap with `vec![E::T(0); 5000].into_boxed_slice()` error: allocating a local array larger than 512000 bytes - --> tests/ui/large_stack_arrays.rs:46:9 + --> tests/ui/large_stack_arrays.rs:49:9 | LL | [0u8; usize::MAX], | ^^^^^^^^^^^^^^^^^ @@ -57,15 +57,7 @@ LL | [0u8; usize::MAX], = help: consider allocating on the heap with `vec![0u8; usize::MAX].into_boxed_slice()` error: allocating a local array larger than 512000 bytes - --> tests/ui/large_stack_arrays.rs:81:25 - | -LL | let y = vec![dummy![[x, x, x, x, x]]]; - | ^^^^^^^^^^^^^^^ - | - = help: consider allocating on the heap with `vec![x, x, x, x, x].into_boxed_slice()` - -error: allocating a local array larger than 512000 bytes - --> tests/ui/large_stack_arrays.rs:84:13 + --> tests/ui/large_stack_arrays.rs:93:13 | LL | let y = [x, x, dummy!(x), x, x]; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +65,7 @@ LL | let y = [x, x, dummy!(x), x, x]; = help: consider allocating on the heap with `vec![x, x, dummy!(x), x, x].into_boxed_slice()` error: allocating a local array larger than 512000 bytes - --> tests/ui/large_stack_arrays.rs:67:13 + --> tests/ui/large_stack_arrays.rs:70:13 | LL | [$a, $b, $a, $b] | ^^^^^^^^^^^^^^^^ @@ -84,12 +76,29 @@ LL | let y = dummy![x => x]; = note: this error originates in the macro `dummy` (in Nightly builds, run with -Z macro-backtrace for more info) error: allocating a local array larger than 512000 bytes - --> tests/ui/large_stack_arrays.rs:89:20 + --> tests/ui/large_stack_arrays.rs:98:20 | LL | let y = dummy![[x, x, x, x, x]]; | ^^^^^^^^^^^^^^^ | = help: consider allocating on the heap with `vec![x, x, x, x, x].into_boxed_slice()` -error: aborting due to 11 previous errors +error: allocating a local array larger than 512000 bytes + --> tests/ui/large_stack_arrays.rs:101:39 + | +LL | let y = proc_macros::make_it_big!([x; 1]); + | ^^^^^^ + +error: allocating a local array larger than 512000 bytes + --> tests/ui/large_stack_arrays.rs:82:23 + | +LL | let _x_ = [$id; $n]; + | ^^^^^^^^^ +... +LL | let y = vec![create_then_move![x; 5]; 5]; + | ----------------------- in this macro invocation + | + = note: this error originates in the macro `create_then_move` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 12 previous errors From 876d5f00a0515f60b23d4e111249d6340159fa8b Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Tue, 16 Apr 2024 19:23:30 -0400 Subject: [PATCH 009/279] Rename `BindingAnnotation` to `BindingMode` --- clippy_lints/src/dereference.rs | 4 ++-- clippy_lints/src/eta_reduction.rs | 4 ++-- clippy_lints/src/explicit_write.rs | 4 ++-- clippy_lints/src/index_refutable_slice.rs | 2 +- clippy_lints/src/let_if_seq.rs | 4 ++-- clippy_lints/src/loops/manual_find.rs | 4 ++-- clippy_lints/src/loops/mut_range_bound.rs | 4 ++-- clippy_lints/src/loops/same_item_push.rs | 4 ++-- clippy_lints/src/manual_hash_one.rs | 4 ++-- clippy_lints/src/matches/manual_utils.rs | 4 ++-- clippy_lints/src/matches/match_as_ref.rs | 4 ++-- clippy_lints/src/matches/needless_match.rs | 4 ++-- clippy_lints/src/matches/single_match.rs | 4 ++-- clippy_lints/src/methods/clone_on_copy.rs | 4 ++-- clippy_lints/src/methods/filter_next.rs | 4 ++-- clippy_lints/src/methods/iter_kv_map.rs | 2 +- .../src/methods/iter_overeager_cloned.rs | 4 ++-- clippy_lints/src/methods/iter_skip_next.rs | 4 ++-- clippy_lints/src/methods/map_clone.rs | 4 ++-- clippy_lints/src/methods/needless_collect.rs | 4 ++-- clippy_lints/src/methods/str_splitn.rs | 6 +++--- clippy_lints/src/misc.rs | 6 +++--- clippy_lints/src/needless_arbitrary_self_type.rs | 6 +++--- clippy_lints/src/needless_borrowed_ref.rs | 6 +++--- clippy_lints/src/needless_late_init.rs | 4 ++-- clippy_lints/src/needless_pass_by_value.rs | 4 ++-- clippy_lints/src/option_if_let_else.rs | 8 ++++---- clippy_lints/src/pass_by_ref_or_value.rs | 4 ++-- clippy_lints/src/ptr.rs | 6 +++--- clippy_lints/src/question_mark.rs | 4 ++-- clippy_lints/src/redundant_locals.rs | 6 +++--- clippy_lints/src/ref_patterns.rs | 4 ++-- clippy_lints/src/reserve_after_initialization.rs | 4 ++-- clippy_lints/src/slow_vector_initialization.rs | 4 ++-- .../src/unnecessary_struct_initialization.rs | 4 ++-- clippy_lints/src/unnested_or_patterns.rs | 4 ++-- clippy_lints/src/useless_conversion.rs | 4 ++-- clippy_lints/src/utils/author.rs | 16 ++++++++-------- clippy_lints/src/vec_init_then_push.rs | 4 ++-- clippy_utils/src/hir_utils.rs | 4 ++-- clippy_utils/src/lib.rs | 4 ++-- tests/ui/author.stdout | 2 +- tests/ui/author/blocks.stdout | 6 +++--- tests/ui/author/loop.stdout | 4 ++-- tests/ui/author/macro_in_closure.stdout | 2 +- tests/ui/author/macro_in_loop.stdout | 2 +- tests/ui/author/matches.stdout | 4 ++-- 47 files changed, 104 insertions(+), 104 deletions(-) diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index f83fb1b90198..bff40c2ae75d 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -9,7 +9,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_errors::Applicability; use rustc_hir::intravisit::{walk_ty, Visitor}; use rustc_hir::{ - self as hir, BindingAnnotation, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node, + self as hir, BindingMode, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node, Pat, PatKind, Path, QPath, TyKind, UnOp, }; use rustc_lint::{LateContext, LateLintPass}; @@ -599,7 +599,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { } fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) { - if let PatKind::Binding(BindingAnnotation::REF, id, name, _) = pat.kind { + if let PatKind::Binding(BindingMode::REF, id, name, _) = pat.kind { if let Some(opt_prev_pat) = self.ref_locals.get_mut(&id) { // This binding id has been seen before. Add this pattern to the list of changes. if let Some(prev_pat) = opt_prev_pat { diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index 850a4f0eec8e..306a4a9e55c9 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -5,7 +5,7 @@ use clippy_utils::ty::type_diagnostic_name; use clippy_utils::usage::{local_used_after_expr, local_used_in}; use clippy_utils::{get_path_from_caller_to_method_type, is_adjusted, path_to_local, path_to_local_id}; use rustc_errors::Applicability; -use rustc_hir::{BindingAnnotation, Expr, ExprKind, FnRetTy, Param, PatKind, QPath, TyKind, Unsafety}; +use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, Param, PatKind, QPath, TyKind, Unsafety}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{ @@ -229,7 +229,7 @@ fn check_inputs( && params.iter().zip(self_arg.into_iter().chain(args)).all(|(p, arg)| { matches!( p.pat.kind, - PatKind::Binding(BindingAnnotation::NONE, id, _, None) + PatKind::Binding(BindingMode::NONE, id, _, None) if path_to_local_id(arg, id) ) // Only allow adjustments which change regions (i.e. re-borrowing). diff --git a/clippy_lints/src/explicit_write.rs b/clippy_lints/src/explicit_write.rs index 33bd5a5a9d3a..724e1843359b 100644 --- a/clippy_lints/src/explicit_write.rs +++ b/clippy_lints/src/explicit_write.rs @@ -4,7 +4,7 @@ use clippy_utils::source::snippet_with_applicability; use clippy_utils::{is_expn_of, path_def_id}; use rustc_errors::Applicability; use rustc_hir::def::Res; -use rustc_hir::{BindingAnnotation, Block, BlockCheckMode, Expr, ExprKind, Node, PatKind, QPath, Stmt, StmtKind}; +use rustc_hir::{BindingMode, Block, BlockCheckMode, Expr, ExprKind, Node, PatKind, QPath, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; use rustc_span::{sym, ExpnId}; @@ -114,7 +114,7 @@ fn look_in_block<'tcx, 'hir>(cx: &LateContext<'tcx>, kind: &'tcx ExprKind<'hir>) && let Node::Pat(res_pat) = cx.tcx.hir_node(expr_res) // Find id of the local we found in the block - && let PatKind::Binding(BindingAnnotation::NONE, local_hir_id, _ident, None) = local.pat.kind + && let PatKind::Binding(BindingMode::NONE, local_hir_id, _ident, None) = local.pat.kind // If those two are the same hir id && res_pat.hir_id == local_hir_id diff --git a/clippy_lints/src/index_refutable_slice.rs b/clippy_lints/src/index_refutable_slice.rs index 6ddc8346511d..799ec9d553d4 100644 --- a/clippy_lints/src/index_refutable_slice.rs +++ b/clippy_lints/src/index_refutable_slice.rs @@ -94,7 +94,7 @@ fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap LateLintPass<'tcx> for LetIfSeq { }; let mutability = match mode { - BindingAnnotation(_, Mutability::Mut) => " ", + BindingMode(_, Mutability::Mut) => " ", _ => "", }; diff --git a/clippy_lints/src/loops/manual_find.rs b/clippy_lints/src/loops/manual_find.rs index d484ce40d785..b27528c11d48 100644 --- a/clippy_lints/src/loops/manual_find.rs +++ b/clippy_lints/src/loops/manual_find.rs @@ -7,7 +7,7 @@ use clippy_utils::{higher, is_res_lang_ctor, path_res, peel_blocks_with_stmt}; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::lang_items::LangItem; -use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, Node, Pat, PatKind, Stmt, StmtKind}; +use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, Node, Pat, PatKind, Stmt, StmtKind}; use rustc_lint::LateContext; use rustc_span::Span; @@ -107,7 +107,7 @@ fn get_binding(pat: &Pat<'_>) -> Option { hir_id = None; return; } - if let BindingAnnotation::NONE = annotation { + if let BindingMode::NONE = annotation { hir_id = Some(id); } }); diff --git a/clippy_lints/src/loops/mut_range_bound.rs b/clippy_lints/src/loops/mut_range_bound.rs index 94330001e4f1..5047092192f4 100644 --- a/clippy_lints/src/loops/mut_range_bound.rs +++ b/clippy_lints/src/loops/mut_range_bound.rs @@ -2,7 +2,7 @@ use super::MUT_RANGE_BOUND; use clippy_utils::diagnostics::span_lint_and_note; use clippy_utils::{get_enclosing_block, higher, path_to_local}; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{BindingAnnotation, Expr, ExprKind, HirId, Node, PatKind}; +use rustc_hir::{BindingMode, Expr, ExprKind, HirId, Node, PatKind}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; @@ -41,7 +41,7 @@ fn mut_warn_with_span(cx: &LateContext<'_>, span: Option) { fn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option { if let Some(hir_id) = path_to_local(bound) && let Node::Pat(pat) = cx.tcx.hir_node(hir_id) - && let PatKind::Binding(BindingAnnotation::MUT, ..) = pat.kind + && let PatKind::Binding(BindingMode::MUT, ..) = pat.kind { return Some(hir_id); } diff --git a/clippy_lints/src/loops/same_item_push.rs b/clippy_lints/src/loops/same_item_push.rs index 1d90d4a58f5e..9185cf1f8b2e 100644 --- a/clippy_lints/src/loops/same_item_push.rs +++ b/clippy_lints/src/loops/same_item_push.rs @@ -7,7 +7,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{walk_expr, Visitor}; -use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, Mutability, Node, Pat, PatKind, Stmt, StmtKind}; +use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, Mutability, Node, Pat, PatKind, Stmt, StmtKind}; use rustc_lint::LateContext; use rustc_span::symbol::sym; use rustc_span::SyntaxContext; @@ -61,7 +61,7 @@ pub(super) fn check<'tcx>( let node = cx.tcx.hir_node(hir_id); if let Node::Pat(pat) = node && let PatKind::Binding(bind_ann, ..) = pat.kind - && !matches!(bind_ann, BindingAnnotation(_, Mutability::Mut)) + && !matches!(bind_ann, BindingMode(_, Mutability::Mut)) && let Node::LetStmt(parent_let_expr) = cx.tcx.parent_hir_node(hir_id) && let Some(init) = parent_let_expr.init { diff --git a/clippy_lints/src/manual_hash_one.rs b/clippy_lints/src/manual_hash_one.rs index f8f33cfc82e9..daa8101aa5ff 100644 --- a/clippy_lints/src/manual_hash_one.rs +++ b/clippy_lints/src/manual_hash_one.rs @@ -4,7 +4,7 @@ use clippy_utils::source::snippet_opt; use clippy_utils::visitors::{is_local_used, local_used_once}; use clippy_utils::{is_trait_method, path_to_local_id}; use rustc_errors::Applicability; -use rustc_hir::{BindingAnnotation, ExprKind, LetStmt, Node, PatKind, StmtKind}; +use rustc_hir::{BindingMode, ExprKind, LetStmt, Node, PatKind, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; use rustc_span::sym; @@ -62,7 +62,7 @@ impl_lint_pass!(ManualHashOne => [MANUAL_HASH_ONE]); impl LateLintPass<'_> for ManualHashOne { fn check_local(&mut self, cx: &LateContext<'_>, local: &LetStmt<'_>) { // `let mut hasher = seg.build_hasher();` - if let PatKind::Binding(BindingAnnotation::MUT, hasher, _, None) = local.pat.kind + if let PatKind::Binding(BindingMode::MUT, hasher, _, None) = local.pat.kind && let Some(init) = local.init && !init.span.from_expansion() && let ExprKind::MethodCall(seg, build_hasher, [], _) = init.kind diff --git a/clippy_lints/src/matches/manual_utils.rs b/clippy_lints/src/matches/manual_utils.rs index 152aba99ce9b..183caab56c59 100644 --- a/clippy_lints/src/matches/manual_utils.rs +++ b/clippy_lints/src/matches/manual_utils.rs @@ -11,7 +11,7 @@ use rustc_ast::util::parser::PREC_POSTFIX; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::LangItem::{OptionNone, OptionSome}; -use rustc_hir::{BindingAnnotation, Expr, ExprKind, HirId, Mutability, Pat, PatKind, Path, QPath}; +use rustc_hir::{BindingMode, Expr, ExprKind, HirId, Mutability, Pat, PatKind, Path, QPath}; use rustc_lint::LateContext; use rustc_span::{sym, SyntaxContext}; @@ -139,7 +139,7 @@ where } // `ref` and `ref mut` annotations were handled earlier. - let annotation = if matches!(annotation, BindingAnnotation::MUT) { + let annotation = if matches!(annotation, BindingMode::MUT) { "mut " } else { "" diff --git a/clippy_lints/src/matches/match_as_ref.rs b/clippy_lints/src/matches/match_as_ref.rs index f5da8ec61874..6c123649afc2 100644 --- a/clippy_lints/src/matches/match_as_ref.rs +++ b/clippy_lints/src/matches/match_as_ref.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; use clippy_utils::{is_res_lang_ctor, path_res, peel_blocks}; use rustc_errors::Applicability; -use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, LangItem, Mutability, PatKind, QPath}; +use rustc_hir::{Arm, BindingMode, ByRef, Expr, ExprKind, LangItem, Mutability, PatKind, QPath}; use rustc_lint::LateContext; use rustc_middle::ty; @@ -67,7 +67,7 @@ fn is_none_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool { fn is_ref_some_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> Option { if let PatKind::TupleStruct(ref qpath, [first_pat, ..], _) = arm.pat.kind && is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), LangItem::OptionSome) - && let PatKind::Binding(BindingAnnotation(ByRef::Yes(mutabl), _), .., ident, _) = first_pat.kind + && let PatKind::Binding(BindingMode(ByRef::Yes(mutabl), _), .., ident, _) = first_pat.kind && let ExprKind::Call(e, [arg]) = peel_blocks(arm.body).kind && is_res_lang_ctor(cx, path_res(cx, e), LangItem::OptionSome) && let ExprKind::Path(QPath::Resolved(_, path2)) = arg.kind diff --git a/clippy_lints/src/matches/needless_match.rs b/clippy_lints/src/matches/needless_match.rs index fe83e784c3c9..6f7d69026404 100644 --- a/clippy_lints/src/matches/needless_match.rs +++ b/clippy_lints/src/matches/needless_match.rs @@ -8,7 +8,7 @@ use clippy_utils::{ }; use rustc_errors::Applicability; use rustc_hir::LangItem::OptionNone; -use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, ItemKind, Node, Pat, PatKind, Path, QPath}; +use rustc_hir::{Arm, BindingMode, ByRef, Expr, ExprKind, ItemKind, Node, Pat, PatKind, Path, QPath}; use rustc_lint::LateContext; use rustc_span::sym; @@ -178,7 +178,7 @@ fn pat_same_as_expr(pat: &Pat<'_>, expr: &Expr<'_>) -> bool { }, )), ) => { - return !matches!(annot, BindingAnnotation(ByRef::Yes(_), _)) && pat_ident.name == first_seg.ident.name; + return !matches!(annot, BindingMode(ByRef::Yes(_), _)) && pat_ident.name == first_seg.ident.name; }, // Example: `Custom::TypeA => Custom::TypeB`, or `None => None` (PatKind::Path(QPath::Resolved(_, p_path)), ExprKind::Path(QPath::Resolved(_, e_path))) => { diff --git a/clippy_lints/src/matches/single_match.rs b/clippy_lints/src/matches/single_match.rs index a0db8e2db1f8..37f72528140f 100644 --- a/clippy_lints/src/matches/single_match.rs +++ b/clippy_lints/src/matches/single_match.rs @@ -4,7 +4,7 @@ use clippy_utils::ty::{implements_trait, is_type_diagnostic_item, peel_mid_ty_re use clippy_utils::{is_lint_allowed, is_unit_expr, is_wild, peel_blocks, peel_hir_pat_refs, peel_n_hir_expr_refs}; use core::cmp::max; use rustc_errors::Applicability; -use rustc_hir::{Arm, BindingAnnotation, Block, Expr, ExprKind, Pat, PatKind}; +use rustc_hir::{Arm, BindingMode, Block, Expr, ExprKind, Pat, PatKind}; use rustc_lint::LateContext; use rustc_middle::ty::{self, Ty}; use rustc_span::{sym, Span}; @@ -166,7 +166,7 @@ fn collect_pat_paths<'a>(acc: &mut Vec>, cx: &LateContext<'a>, pat: &Pat< let p_ty = cx.typeck_results().pat_ty(p); collect_pat_paths(acc, cx, p, p_ty); }), - PatKind::TupleStruct(..) | PatKind::Binding(BindingAnnotation::NONE, .., None) | PatKind::Path(_) => { + PatKind::TupleStruct(..) | PatKind::Binding(BindingMode::NONE, .., None) | PatKind::Path(_) => { acc.push(ty); }, _ => {}, diff --git a/clippy_lints/src/methods/clone_on_copy.rs b/clippy_lints/src/methods/clone_on_copy.rs index 4e6823e8220b..e7a2060be046 100644 --- a/clippy_lints/src/methods/clone_on_copy.rs +++ b/clippy_lints/src/methods/clone_on_copy.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_context; use clippy_utils::ty::is_copy; use rustc_errors::Applicability; -use rustc_hir::{BindingAnnotation, ByRef, Expr, ExprKind, MatchSource, Node, PatKind, QPath}; +use rustc_hir::{BindingMode, ByRef, Expr, ExprKind, MatchSource, Node, PatKind, QPath}; use rustc_lint::LateContext; use rustc_middle::ty::adjustment::Adjust; use rustc_middle::ty::print::with_forced_trimmed_paths; @@ -69,7 +69,7 @@ pub(super) fn check( _ => false, }, // local binding capturing a reference - Node::LetStmt(l) if matches!(l.pat.kind, PatKind::Binding(BindingAnnotation(ByRef::Yes(_), _), ..)) => { + Node::LetStmt(l) if matches!(l.pat.kind, PatKind::Binding(BindingMode(ByRef::Yes(_), _), ..)) => { return; }, _ => false, diff --git a/clippy_lints/src/methods/filter_next.rs b/clippy_lints/src/methods/filter_next.rs index 7339362193e5..e697ba656f5f 100644 --- a/clippy_lints/src/methods/filter_next.rs +++ b/clippy_lints/src/methods/filter_next.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; use clippy_utils::source::snippet; use clippy_utils::ty::implements_trait; -use rustc_ast::{BindingAnnotation, Mutability}; +use rustc_ast::{BindingMode, Mutability}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; @@ -45,7 +45,7 @@ pub(super) fn check<'tcx>( span_lint_and_then(cx, FILTER_NEXT, expr.span, msg, |diag| { let (applicability, pat) = if let Some(id) = path_to_local(recv) && let hir::Node::Pat(pat) = cx.tcx.hir_node(id) - && let hir::PatKind::Binding(BindingAnnotation(_, Mutability::Not), _, ident, _) = pat.kind + && let hir::PatKind::Binding(BindingMode(_, Mutability::Not), _, ident, _) = pat.kind { (Applicability::Unspecified, Some((pat.span, ident))) } else { diff --git a/clippy_lints/src/methods/iter_kv_map.rs b/clippy_lints/src/methods/iter_kv_map.rs index b9fec0c4f80a..7c852a3768d1 100644 --- a/clippy_lints/src/methods/iter_kv_map.rs +++ b/clippy_lints/src/methods/iter_kv_map.rs @@ -6,7 +6,7 @@ use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_sugg, span_lint_an use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::{pat_is_wild, sugg}; -use rustc_hir::{BindingAnnotation, Body, BorrowKind, ByRef, Expr, ExprKind, Mutability, Pat, PatKind}; +use rustc_hir::{BindingMode, Body, BorrowKind, ByRef, Expr, ExprKind, Mutability, Pat, PatKind}; use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty; use rustc_span::{sym, Span}; diff --git a/clippy_lints/src/methods/iter_overeager_cloned.rs b/clippy_lints/src/methods/iter_overeager_cloned.rs index 4729481320eb..6d70989546a2 100644 --- a/clippy_lints/src/methods/iter_overeager_cloned.rs +++ b/clippy_lints/src/methods/iter_overeager_cloned.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet_opt; use clippy_utils::ty::{implements_trait, is_copy}; -use rustc_ast::BindingAnnotation; +use rustc_ast::BindingMode; use rustc_errors::Applicability; use rustc_hir::{Body, Expr, ExprKind, HirId, HirIdSet, PatKind}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; @@ -89,7 +89,7 @@ pub(super) fn check<'tcx>( } match it.kind { - PatKind::Binding(BindingAnnotation(_, Mutability::Mut), _, _, _) + PatKind::Binding(BindingMode(_, Mutability::Mut), _, _, _) | PatKind::Ref(_, Mutability::Mut) => { to_be_discarded = true; false diff --git a/clippy_lints/src/methods/iter_skip_next.rs b/clippy_lints/src/methods/iter_skip_next.rs index d1215290dada..fedb7c22eded 100644 --- a/clippy_lints/src/methods/iter_skip_next.rs +++ b/clippy_lints/src/methods/iter_skip_next.rs @@ -3,7 +3,7 @@ use clippy_utils::source::snippet; use clippy_utils::{is_trait_method, path_to_local}; use rustc_errors::Applicability; use rustc_hir as hir; -use rustc_hir::{BindingAnnotation, Node, PatKind}; +use rustc_hir::{BindingMode, Node, PatKind}; use rustc_lint::LateContext; use rustc_span::sym; @@ -22,7 +22,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr if let Some(id) = path_to_local(recv) && let Node::Pat(pat) = cx.tcx.hir_node(id) && let PatKind::Binding(ann, _, _, _) = pat.kind - && ann != BindingAnnotation::MUT + && ann != BindingMode::MUT { application = Applicability::Unspecified; diag.span_help( diff --git a/clippy_lints/src/methods/map_clone.rs b/clippy_lints/src/methods/map_clone.rs index 0901268e9bdc..a5ba5e5d8918 100644 --- a/clippy_lints/src/methods/map_clone.rs +++ b/clippy_lints/src/methods/map_clone.rs @@ -51,13 +51,13 @@ pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_ let closure_expr = peel_blocks(closure_body.value); match closure_body.params[0].pat.kind { hir::PatKind::Ref(inner, Mutability::Not) => { - if let hir::PatKind::Binding(hir::BindingAnnotation::NONE, .., name, None) = inner.kind { + if let hir::PatKind::Binding(hir::BindingMode::NONE, .., name, None) = inner.kind { if ident_eq(name, closure_expr) { lint_explicit_closure(cx, e.span, recv.span, true, msrv); } } }, - hir::PatKind::Binding(hir::BindingAnnotation::NONE, .., name, None) => { + hir::PatKind::Binding(hir::BindingMode::NONE, .., name, None) => { match closure_expr.kind { hir::ExprKind::Unary(hir::UnOp::Deref, inner) => { if ident_eq(name, inner) { diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs index 662e7746496a..1c695655536c 100644 --- a/clippy_lints/src/methods/needless_collect.rs +++ b/clippy_lints/src/methods/needless_collect.rs @@ -11,7 +11,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Applicability, MultiSpan}; use rustc_hir::intravisit::{walk_block, walk_expr, Visitor}; use rustc_hir::{ - BindingAnnotation, Block, Expr, ExprKind, HirId, HirIdSet, LetStmt, Mutability, Node, PatKind, Stmt, StmtKind, + BindingMode, Block, Expr, ExprKind, HirId, HirIdSet, LetStmt, Mutability, Node, PatKind, Stmt, StmtKind, }; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; @@ -86,7 +86,7 @@ pub(super) fn check<'tcx>( } }, Node::LetStmt(l) => { - if let PatKind::Binding(BindingAnnotation::NONE | BindingAnnotation::MUT, id, _, None) = l.pat.kind + if let PatKind::Binding(BindingMode::NONE | BindingMode::MUT, id, _, None) = l.pat.kind && let ty = cx.typeck_results().expr_ty(collect_expr) && [sym::Vec, sym::VecDeque, sym::BinaryHeap, sym::LinkedList] .into_iter() diff --git a/clippy_lints/src/methods/str_splitn.rs b/clippy_lints/src/methods/str_splitn.rs index 55ae9746298f..e8c12bbeea0e 100644 --- a/clippy_lints/src/methods/str_splitn.rs +++ b/clippy_lints/src/methods/str_splitn.rs @@ -8,7 +8,7 @@ use clippy_utils::{is_diag_item_method, match_def_path, path_to_local_id, paths} use core::ops::ControlFlow; use rustc_errors::Applicability; use rustc_hir::{ - BindingAnnotation, Expr, ExprKind, HirId, LangItem, LetStmt, MatchSource, Node, Pat, PatKind, QPath, Stmt, StmtKind, + BindingMode, Expr, ExprKind, HirId, LangItem, LetStmt, MatchSource, Node, Pat, PatKind, QPath, Stmt, StmtKind, }; use rustc_lint::LateContext; use rustc_middle::ty; @@ -129,7 +129,7 @@ fn check_manual_split_once_indirect( let ctxt = expr.span.ctxt(); let mut parents = cx.tcx.hir().parent_iter(expr.hir_id); if let (_, Node::LetStmt(local)) = parents.next()? - && let PatKind::Binding(BindingAnnotation::MUT, iter_binding_id, iter_ident, None) = local.pat.kind + && let PatKind::Binding(BindingMode::MUT, iter_binding_id, iter_ident, None) = local.pat.kind && let (iter_stmt_id, Node::Stmt(_)) = parents.next()? && let (_, Node::Block(enclosing_block)) = parents.next()? && let mut stmts = enclosing_block @@ -200,7 +200,7 @@ fn indirect_usage<'tcx>( ) -> Option> { if let StmtKind::Let(&LetStmt { pat: Pat { - kind: PatKind::Binding(BindingAnnotation::NONE, _, ident, None), + kind: PatKind::Binding(BindingMode::NONE, _, ident, None), .. }, init: Some(init_expr), diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 3cf054e72071..f3f9bf11a61c 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -9,7 +9,7 @@ use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::intravisit::FnKind; use rustc_hir::{ - BinOpKind, BindingAnnotation, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, QPath, Stmt, StmtKind, + BinOpKind, BindingMode, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, QPath, Stmt, StmtKind, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; @@ -129,7 +129,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass { if !is_lint_allowed(cx, REF_PATTERNS, arg.pat.hir_id) { return; } - if let PatKind::Binding(BindingAnnotation(ByRef::Yes(_), _), ..) = arg.pat.kind { + if let PatKind::Binding(BindingMode(ByRef::Yes(_), _), ..) = arg.pat.kind { span_lint( cx, TOPLEVEL_REF_ARG, @@ -144,7 +144,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass { fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) { if !in_external_macro(cx.tcx.sess, stmt.span) && let StmtKind::Let(local) = stmt.kind - && let PatKind::Binding(BindingAnnotation(ByRef::Yes(mutabl), _), .., name, None) = local.pat.kind + && let PatKind::Binding(BindingMode(ByRef::Yes(mutabl), _), .., name, None) = local.pat.kind && let Some(init) = local.init // Do not emit if clippy::ref_patterns is not allowed to avoid having two lints for the same issue. && is_lint_allowed(cx, REF_PATTERNS, local.pat.hir_id) diff --git a/clippy_lints/src/needless_arbitrary_self_type.rs b/clippy_lints/src/needless_arbitrary_self_type.rs index 2ab83f733cb1..60c44382059a 100644 --- a/clippy_lints/src/needless_arbitrary_self_type.rs +++ b/clippy_lints/src/needless_arbitrary_self_type.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use rustc_ast::ast::{BindingAnnotation, ByRef, Lifetime, Mutability, Param, PatKind, Path, TyKind}; +use rustc_ast::ast::{BindingMode, ByRef, Lifetime, Mutability, Param, PatKind, Path, TyKind}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::declare_lint_pass; @@ -117,13 +117,13 @@ impl EarlyLintPass for NeedlessArbitrarySelfType { match &p.ty.kind { TyKind::Path(None, path) => { - if let PatKind::Ident(BindingAnnotation(ByRef::No, mutbl), _, _) = p.pat.kind { + if let PatKind::Ident(BindingMode(ByRef::No, mutbl), _, _) = p.pat.kind { check_param_inner(cx, path, p.span.to(p.ty.span), &Mode::Value, mutbl); } }, TyKind::Ref(lifetime, mut_ty) => { if let TyKind::Path(None, path) = &mut_ty.ty.kind - && let PatKind::Ident(BindingAnnotation::NONE, _, _) = p.pat.kind + && let PatKind::Ident(BindingMode::NONE, _, _) = p.pat.kind { check_param_inner(cx, path, p.span.to(p.ty.span), &Mode::Ref(*lifetime), mut_ty.mutbl); } diff --git a/clippy_lints/src/needless_borrowed_ref.rs b/clippy_lints/src/needless_borrowed_ref.rs index d91329eadcb4..fb02f24c9dc6 100644 --- a/clippy_lints/src/needless_borrowed_ref.rs +++ b/clippy_lints/src/needless_borrowed_ref.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use rustc_errors::Applicability; -use rustc_hir::{BindingAnnotation, Mutability, Node, Pat, PatKind}; +use rustc_hir::{BindingMode, Mutability, Node, Pat, PatKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; @@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef { match pat.kind { // Check sub_pat got a `ref` keyword (excluding `ref mut`). - PatKind::Binding(BindingAnnotation::REF, _, ident, None) => { + PatKind::Binding(BindingMode::REF, _, ident, None) => { span_lint_and_then( cx, NEEDLESS_BORROWED_REFERENCE, @@ -128,7 +128,7 @@ fn check_subpatterns<'tcx>( for subpattern in subpatterns { match subpattern.kind { - PatKind::Binding(BindingAnnotation::REF, _, ident, None) => { + PatKind::Binding(BindingMode::REF, _, ident, None) => { // `ref ident` // ^^^^ let span = subpattern.span.until(ident.span); diff --git a/clippy_lints/src/needless_late_init.rs b/clippy_lints/src/needless_late_init.rs index 810799acb2e2..0c0b1a73351f 100644 --- a/clippy_lints/src/needless_late_init.rs +++ b/clippy_lints/src/needless_late_init.rs @@ -6,7 +6,7 @@ use clippy_utils::visitors::{for_each_expr, for_each_expr_with_closures, is_loca use core::ops::ControlFlow; use rustc_errors::{Applicability, MultiSpan}; use rustc_hir::{ - BindingAnnotation, Block, Expr, ExprKind, HirId, LetStmt, LocalSource, MatchSource, Node, Pat, PatKind, Stmt, + BindingMode, Block, Expr, ExprKind, HirId, LetStmt, LocalSource, MatchSource, Node, Pat, PatKind, Stmt, StmtKind, }; use rustc_lint::{LateContext, LateLintPass}; @@ -369,7 +369,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessLateInit { init: None, pat: &Pat { - kind: PatKind::Binding(BindingAnnotation::NONE, binding_id, _, None), + kind: PatKind::Binding(BindingMode::NONE, binding_id, _, None), .. }, source: LocalSource::Normal, diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index f33e2e0ed71a..53bcde680876 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -9,7 +9,7 @@ use rustc_ast::ast::Attribute; use rustc_errors::{Applicability, Diag}; use rustc_hir::intravisit::FnKind; use rustc_hir::{ - BindingAnnotation, Body, FnDecl, GenericArg, HirId, HirIdSet, Impl, ItemKind, LangItem, Mutability, Node, PatKind, + BindingMode, Body, FnDecl, GenericArg, HirId, HirIdSet, Impl, ItemKind, LangItem, Mutability, Node, PatKind, QPath, TyKind, }; use rustc_hir_typeck::expr_use_visitor as euv; @@ -192,7 +192,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { }) && !implements_borrow_trait && !all_borrowable_trait - && let PatKind::Binding(BindingAnnotation(_, Mutability::Not), canonical_id, ..) = arg.pat.kind + && let PatKind::Binding(BindingMode(_, Mutability::Not), canonical_id, ..) = arg.pat.kind && !moved_vars.contains(&canonical_id) { // Dereference suggestion diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs index 3cbd03a58c55..d4906328ccb9 100644 --- a/clippy_lints/src/option_if_let_else.rs +++ b/clippy_lints/src/option_if_let_else.rs @@ -7,7 +7,7 @@ use clippy_utils::{ use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk}; -use rustc_hir::{Arm, BindingAnnotation, Expr, ExprKind, MatchSource, Mutability, Pat, PatKind, Path, QPath, UnOp}; +use rustc_hir::{Arm, BindingMode, Expr, ExprKind, MatchSource, Mutability, Pat, PatKind, Path, QPath, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; use rustc_span::SyntaxContext; @@ -129,7 +129,7 @@ fn try_get_option_occurrence<'tcx>( .filter_map(|(id, &c)| none_captures.get(id).map(|&c2| (c, c2))) .all(|(x, y)| x.is_imm_ref() && y.is_imm_ref()) { - let capture_mut = if bind_annotation == BindingAnnotation::MUT { + let capture_mut = if bind_annotation == BindingMode::MUT { "mut " } else { "" @@ -149,8 +149,8 @@ fn try_get_option_occurrence<'tcx>( (mutb == Mutability::Not, mutb == Mutability::Mut) }, _ => ( - bind_annotation == BindingAnnotation::REF, - bind_annotation == BindingAnnotation::REF_MUT, + bind_annotation == BindingMode::REF, + bind_annotation == BindingMode::REF_MUT, ), }; diff --git a/clippy_lints/src/pass_by_ref_or_value.rs b/clippy_lints/src/pass_by_ref_or_value.rs index bb4a1de9f77d..128bfd49d9e5 100644 --- a/clippy_lints/src/pass_by_ref_or_value.rs +++ b/clippy_lints/src/pass_by_ref_or_value.rs @@ -10,7 +10,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::intravisit::FnKind; -use rustc_hir::{BindingAnnotation, Body, FnDecl, Impl, ItemKind, MutTy, Mutability, Node, PatKind}; +use rustc_hir::{BindingMode, Body, FnDecl, Impl, ItemKind, MutTy, Mutability, Node, PatKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::adjustment::{Adjust, PointerCoercion}; use rustc_middle::ty::layout::LayoutOf; @@ -221,7 +221,7 @@ impl<'tcx> PassByRefOrValue { // if function has a body and parameter is annotated with mut, ignore if let Some(param) = fn_body.and_then(|body| body.params.get(index)) { match param.pat.kind { - PatKind::Binding(BindingAnnotation::NONE, _, _, _) => {}, + PatKind::Binding(BindingMode::NONE, _, _, _) => {}, _ => continue, } } diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index d6592622f0bb..cc61ef9184cd 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -11,7 +11,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::hir_id::{HirId, HirIdMap}; use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::{ - self as hir, AnonConst, BinOpKind, BindingAnnotation, Body, Expr, ExprKind, FnRetTy, FnSig, GenericArg, + self as hir, AnonConst, BinOpKind, BindingMode, Body, Expr, ExprKind, FnRetTy, FnSig, GenericArg, ImplItemKind, ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, TraitFn, TraitItem, TraitItemKind, TyKind, Unsafety, }; @@ -606,7 +606,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args: Some((Node::Stmt(_), _)) => (), Some((Node::LetStmt(l), _)) => { // Only trace simple bindings. e.g `let x = y;` - if let PatKind::Binding(BindingAnnotation::NONE, id, _, None) = l.pat.kind { + if let PatKind::Binding(BindingMode::NONE, id, _, None) = l.pat.kind { self.bindings.insert(id, args_idx); } else { set_skip_flag(); @@ -687,7 +687,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args: .filter_map(|(i, arg)| { let param = &body.params[arg.idx]; match param.pat.kind { - PatKind::Binding(BindingAnnotation::NONE, id, _, None) + PatKind::Binding(BindingMode::NONE, id, _, None) if !is_lint_allowed(cx, PTR_ARG, param.hir_id) => { Some((id, i)) diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index 927c6f1d519e..4ad967589a54 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -14,7 +14,7 @@ use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::LangItem::{self, OptionNone, OptionSome, ResultErr, ResultOk}; use rustc_hir::{ - BindingAnnotation, Block, Body, ByRef, Expr, ExprKind, LetStmt, Mutability, Node, PatKind, PathSegment, QPath, + BindingMode, Block, Body, ByRef, Expr, ExprKind, LetStmt, Mutability, Node, PatKind, PathSegment, QPath, Stmt, StmtKind, }; use rustc_lint::{LateContext, LateLintPass}; @@ -283,7 +283,7 @@ fn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: && !is_else_clause(cx.tcx, expr) && let PatKind::TupleStruct(ref path1, [field], ddpos) = let_pat.kind && ddpos.as_opt_usize().is_none() - && let PatKind::Binding(BindingAnnotation(by_ref, _), bind_id, ident, None) = field.kind + && let PatKind::Binding(BindingMode(by_ref, _), bind_id, ident, None) = field.kind && let caller_ty = cx.typeck_results().expr_ty(let_expr) && let if_block = IfBlockType::IfLet( cx.qpath_res(path1, let_pat.hir_id), diff --git a/clippy_lints/src/redundant_locals.rs b/clippy_lints/src/redundant_locals.rs index 7202266deeb2..d94ca5bc7ec2 100644 --- a/clippy_lints/src/redundant_locals.rs +++ b/clippy_lints/src/redundant_locals.rs @@ -3,7 +3,7 @@ use clippy_utils::is_from_proc_macro; use clippy_utils::ty::needs_ordered_drop; use rustc_ast::Mutability; use rustc_hir::def::Res; -use rustc_hir::{BindingAnnotation, ByRef, ExprKind, HirId, LetStmt, Node, Pat, PatKind, QPath}; +use rustc_hir::{BindingMode, ByRef, ExprKind, HirId, LetStmt, Node, Pat, PatKind, QPath}; use rustc_hir_typeck::expr_use_visitor::PlaceBase; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; @@ -50,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) { if !local.span.is_desugaring(DesugaringKind::Async) // the pattern is a single by-value binding - && let PatKind::Binding(BindingAnnotation(ByRef::No, mutability), _, ident, None) = local.pat.kind + && let PatKind::Binding(BindingMode(ByRef::No, mutability), _, ident, None) = local.pat.kind // the binding is not type-ascribed && local.ty.is_none() // the expression is a resolved path @@ -109,7 +109,7 @@ fn is_by_value_closure_capture(cx: &LateContext<'_>, redefinition: HirId, root_v } /// Find the annotation of a binding introduced by a pattern, or `None` if it's not introduced. -fn find_binding(pat: &Pat<'_>, name: Ident) -> Option { +fn find_binding(pat: &Pat<'_>, name: Ident) -> Option { let mut ret = None; pat.each_binding_or_first(&mut |annotation, _, _, ident| { diff --git a/clippy_lints/src/ref_patterns.rs b/clippy_lints/src/ref_patterns.rs index a4be78b310b4..607a0740b843 100644 --- a/clippy_lints/src/ref_patterns.rs +++ b/clippy_lints/src/ref_patterns.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_help; -use rustc_ast::ast::{BindingAnnotation, Pat, PatKind}; +use rustc_ast::ast::{BindingMode, Pat, PatKind}; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::declare_lint_pass; @@ -28,7 +28,7 @@ declare_lint_pass!(RefPatterns => [REF_PATTERNS]); impl EarlyLintPass for RefPatterns { fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &Pat) { - if let PatKind::Ident(BindingAnnotation::REF, _, _) = pat.kind + if let PatKind::Ident(BindingMode::REF, _, _) = pat.kind && !pat.span.from_expansion() { span_lint_and_help( diff --git a/clippy_lints/src/reserve_after_initialization.rs b/clippy_lints/src/reserve_after_initialization.rs index c227b5b22f4d..caf3fb8707da 100644 --- a/clippy_lints/src/reserve_after_initialization.rs +++ b/clippy_lints/src/reserve_after_initialization.rs @@ -4,7 +4,7 @@ use clippy_utils::source::snippet; use clippy_utils::{is_from_proc_macro, path_to_local_id}; use rustc_errors::Applicability; use rustc_hir::def::Res; -use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, LetStmt, PatKind, QPath, Stmt, StmtKind}; +use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, LetStmt, PatKind, QPath, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::impl_lint_pass; @@ -71,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for ReserveAfterInitialization { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) { if let Some(init_expr) = local.init - && let PatKind::Binding(BindingAnnotation::MUT, id, _, None) = local.pat.kind + && let PatKind::Binding(BindingMode::MUT, id, _, None) = local.pat.kind && !in_external_macro(cx.sess(), local.span) && let Some(init) = get_vec_init_kind(cx, init_expr) && !matches!( diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs index 8a9f02b6dcb1..28c254537abd 100644 --- a/clippy_lints/src/slow_vector_initialization.rs +++ b/clippy_lints/src/slow_vector_initialization.rs @@ -7,7 +7,7 @@ use clippy_utils::{ }; use rustc_errors::Applicability; use rustc_hir::intravisit::{walk_block, walk_expr, walk_stmt, Visitor}; -use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, PatKind, Stmt, StmtKind}; +use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, PatKind, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; use rustc_span::symbol::sym; @@ -120,7 +120,7 @@ impl<'tcx> LateLintPass<'tcx> for SlowVectorInit { // Matches statements which initializes vectors. For example: `let mut vec = Vec::with_capacity(10)` // or `Vec::new()` if let StmtKind::Let(local) = stmt.kind - && let PatKind::Binding(BindingAnnotation::MUT, local_id, _, None) = local.pat.kind + && let PatKind::Binding(BindingMode::MUT, local_id, _, None) = local.pat.kind && let Some(init) = local.init && let Some(size_expr) = Self::as_vec_initializer(cx, init) { diff --git a/clippy_lints/src/unnecessary_struct_initialization.rs b/clippy_lints/src/unnecessary_struct_initialization.rs index 333ea0c82df6..2da753343448 100644 --- a/clippy_lints/src/unnecessary_struct_initialization.rs +++ b/clippy_lints/src/unnecessary_struct_initialization.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; use clippy_utils::ty::is_copy; use clippy_utils::{get_parent_expr, path_to_local}; -use rustc_hir::{BindingAnnotation, Expr, ExprKind, Node, PatKind, UnOp}; +use rustc_hir::{BindingMode, Expr, ExprKind, Node, PatKind, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; @@ -84,7 +84,7 @@ fn is_mutable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { if let Some(hir_id) = path_to_local(expr) && let Node::Pat(pat) = cx.tcx.hir_node(hir_id) { - matches!(pat.kind, PatKind::Binding(BindingAnnotation::MUT, ..)) + matches!(pat.kind, PatKind::Binding(BindingMode::MUT, ..)) } else { true } diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs index 0049de931f4f..fcc41b51542f 100644 --- a/clippy_lints/src/unnested_or_patterns.rs +++ b/clippy_lints/src/unnested_or_patterns.rs @@ -137,12 +137,12 @@ fn insert_necessary_parens(pat: &mut P) { struct Visitor; impl MutVisitor for Visitor { fn visit_pat(&mut self, pat: &mut P) { - use ast::BindingAnnotation; + use ast::BindingMode; noop_visit_pat(pat, self); let target = match &mut pat.kind { // `i @ a | b`, `box a | b`, and `& mut? a | b`. Ident(.., Some(p)) | Box(p) | Ref(p, _) if matches!(&p.kind, Or(ps) if ps.len() > 1) => p, - Ref(p, Mutability::Not) if matches!(p.kind, Ident(BindingAnnotation::MUT, ..)) => p, // `&(mut x)` + Ref(p, Mutability::Not) if matches!(p.kind, Ident(BindingMode::MUT, ..)) => p, // `&(mut x)` _ => return, }; target.kind = Paren(P(take_pat(target))); diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs index 755417661565..2f7d54e73ed7 100644 --- a/clippy_lints/src/useless_conversion.rs +++ b/clippy_lints/src/useless_conversion.rs @@ -5,7 +5,7 @@ use clippy_utils::ty::{is_copy, is_type_diagnostic_item, same_type_and_consts}; use clippy_utils::{get_parent_expr, is_trait_method, is_ty_alias, path_to_local}; use rustc_errors::Applicability; use rustc_hir::def_id::DefId; -use rustc_hir::{BindingAnnotation, Expr, ExprKind, HirId, MatchSource, Node, PatKind}; +use rustc_hir::{BindingMode, Expr, ExprKind, HirId, MatchSource, Node, PatKind}; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::Obligation; use rustc_lint::{LateContext, LateLintPass}; @@ -282,7 +282,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { if let Some(id) = path_to_local(recv) && let Node::Pat(pat) = cx.tcx.hir_node(id) && let PatKind::Binding(ann, ..) = pat.kind - && ann != BindingAnnotation::MUT + && ann != BindingMode::MUT { // Do not remove .into_iter() applied to a non-mutable local variable used in // a larger expression context as it would differ in mutability. diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 7b43abeef671..7f0769452c73 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -7,7 +7,7 @@ use rustc_ast::LitIntType; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::{ - ArrayLen, BindingAnnotation, CaptureBy, Closure, ClosureKind, CoroutineKind, ExprKind, FnRetTy, HirId, Lit, + ArrayLen, BindingMode, CaptureBy, Closure, ClosureKind, CoroutineKind, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; @@ -645,14 +645,14 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { bind!(self, name); opt_bind!(self, sub); let ann = match ann { - BindingAnnotation::NONE => "NONE", - BindingAnnotation::REF => "REF", - BindingAnnotation::MUT => "MUT", - BindingAnnotation::REF_MUT => "REF_MUT", - BindingAnnotation::MUT_REF => "MUT_REF", - BindingAnnotation::MUT_REF_MUT => "MUT_REF_MUT", + BindingMode::NONE => "NONE", + BindingMode::REF => "REF", + BindingMode::MUT => "MUT", + BindingMode::REF_MUT => "REF_MUT", + BindingMode::MUT_REF => "MUT_REF", + BindingMode::MUT_REF_MUT => "MUT_REF_MUT", }; - kind!("Binding(BindingAnnotation::{ann}, _, {name}, {sub})"); + kind!("Binding(BindingMode::{ann}, _, {name}, {sub})"); self.ident(name); sub.if_some(|p| self.pat(p)); }, diff --git a/clippy_lints/src/vec_init_then_push.rs b/clippy_lints/src/vec_init_then_push.rs index b58a4fb84746..c46f0298cc8b 100644 --- a/clippy_lints/src/vec_init_then_push.rs +++ b/clippy_lints/src/vec_init_then_push.rs @@ -7,7 +7,7 @@ use core::ops::ControlFlow; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::{ - BindingAnnotation, Block, Expr, ExprKind, HirId, LetStmt, Mutability, PatKind, QPath, Stmt, StmtKind, UnOp, + BindingMode, Block, Expr, ExprKind, HirId, LetStmt, Mutability, PatKind, QPath, Stmt, StmtKind, UnOp, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; @@ -159,7 +159,7 @@ impl<'tcx> LateLintPass<'tcx> for VecInitThenPush { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) { if let Some(init_expr) = local.init - && let PatKind::Binding(BindingAnnotation::MUT, id, name, None) = local.pat.kind + && let PatKind::Binding(BindingMode::MUT, id, name, None) = local.pat.kind && !in_external_macro(cx.sess(), local.span) && let Some(init) = get_vec_init_kind(cx, init_expr) && !matches!(init, VecInitKind::WithExprCapacity(_)) diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 6c3d93299322..07c443acb05f 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -7,7 +7,7 @@ use rustc_data_structures::fx::FxHasher; use rustc_hir::def::Res; use rustc_hir::MatchSource::TryDesugar; use rustc_hir::{ - ArrayLen, BinOpKind, BindingAnnotation, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg, + ArrayLen, BinOpKind, BindingMode, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName, Pat, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding, }; @@ -947,7 +947,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { pub fn hash_pat(&mut self, pat: &Pat<'_>) { std::mem::discriminant(&pat.kind).hash(&mut self.s); match pat.kind { - PatKind::Binding(BindingAnnotation(by_ref, mutability), _, _, pat) => { + PatKind::Binding(BindingMode(by_ref, mutability), _, _, pat) => { std::mem::discriminant(&by_ref).hash(&mut self.s); std::mem::discriminant(&mutability).hash(&mut self.s); if let Some(pat) = pat { diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 37c12dd850c2..aac699eed239 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -99,7 +99,7 @@ use rustc_hir::hir_id::{HirIdMap, HirIdSet}; use rustc_hir::intravisit::{walk_expr, FnKind, Visitor}; use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk}; use rustc_hir::{ - self as hir, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, ByRef, Closure, Destination, Expr, + self as hir, def, Arm, ArrayLen, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp, @@ -184,7 +184,7 @@ pub fn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr /// canonical binding `HirId`. pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> { if let Node::Pat(pat) = cx.tcx.hir_node(hir_id) - && matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..)) + && matches!(pat.kind, PatKind::Binding(BindingMode::NONE, ..)) && let Node::LetStmt(local) = cx.tcx.parent_hir_node(hir_id) { return local.init; diff --git a/tests/ui/author.stdout b/tests/ui/author.stdout index 27ad538f24d8..d448db097a7e 100644 --- a/tests/ui/author.stdout +++ b/tests/ui/author.stdout @@ -5,7 +5,7 @@ if let StmtKind::Local(local) = stmt.kind && match_qpath(qpath, &["char"]) && let ExprKind::Lit(ref lit) = expr.kind && let LitKind::Int(69, LitIntType::Unsuffixed) = lit.node - && let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind + && let PatKind::Binding(BindingMode::NONE, _, name, None) = local.pat.kind && name.as_str() == "x" { // report your lint here diff --git a/tests/ui/author/blocks.stdout b/tests/ui/author/blocks.stdout index 579f137f861e..80b928dd6cb5 100644 --- a/tests/ui/author/blocks.stdout +++ b/tests/ui/author/blocks.stdout @@ -4,13 +4,13 @@ if let ExprKind::Block(block, None) = expr.kind && let Some(init) = local.init && let ExprKind::Lit(ref lit) = init.kind && let LitKind::Int(42, LitIntType::Signed(IntTy::I32)) = lit.node - && let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind + && let PatKind::Binding(BindingMode::NONE, _, name, None) = local.pat.kind && name.as_str() == "x" && let StmtKind::Local(local1) = block.stmts[1].kind && let Some(init1) = local1.init && let ExprKind::Lit(ref lit1) = init1.kind && let LitKind::Float(_, LitFloatType::Suffixed(FloatTy::F32)) = lit1.node - && let PatKind::Binding(BindingAnnotation::NONE, _, name1, None) = local1.pat.kind + && let PatKind::Binding(BindingMode::NONE, _, name1, None) = local1.pat.kind && name1.as_str() == "_t" && let StmtKind::Semi(e) = block.stmts[2].kind && let ExprKind::Unary(UnOp::Neg, inner) = e.kind @@ -28,7 +28,7 @@ if let ExprKind::Block(block, None) = expr.kind && let ExprKind::Path(ref qpath) = func.kind && match_qpath(qpath, &["String", "new"]) && args.is_empty() - && let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind + && let PatKind::Binding(BindingMode::NONE, _, name, None) = local.pat.kind && name.as_str() == "expr" && let Some(trailing_expr) = block.expr && let ExprKind::Call(func1, args1) = trailing_expr.kind diff --git a/tests/ui/author/loop.stdout b/tests/ui/author/loop.stdout index 94a6436ed547..631105a2238d 100644 --- a/tests/ui/author/loop.stdout +++ b/tests/ui/author/loop.stdout @@ -1,5 +1,5 @@ if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::ForLoop::hir(expr) - && let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = pat.kind + && let PatKind::Binding(BindingMode::NONE, _, name, None) = pat.kind && name.as_str() == "y" && let ExprKind::Struct(qpath, fields, None) = arg.kind && matches!(qpath, QPath::LangItem(LangItem::Range, _)) @@ -16,7 +16,7 @@ if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::Fo && let Some(init) = local.init && let ExprKind::Path(ref qpath1) = init.kind && match_qpath(qpath1, &["y"]) - && let PatKind::Binding(BindingAnnotation::NONE, _, name1, None) = local.pat.kind + && let PatKind::Binding(BindingMode::NONE, _, name1, None) = local.pat.kind && name1.as_str() == "z" && block.expr.is_none() { diff --git a/tests/ui/author/macro_in_closure.stdout b/tests/ui/author/macro_in_closure.stdout index f2e54c2c1c86..b90c830e0307 100644 --- a/tests/ui/author/macro_in_closure.stdout +++ b/tests/ui/author/macro_in_closure.stdout @@ -34,7 +34,7 @@ if let StmtKind::Local(local) = stmt.kind && let ExprKind::Path(ref qpath3) = inner2.kind && match_qpath(qpath3, &["x"]) && block.expr.is_none() - && let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind + && let PatKind::Binding(BindingMode::NONE, _, name, None) = local.pat.kind && name.as_str() == "print_text" { // report your lint here diff --git a/tests/ui/author/macro_in_loop.stdout b/tests/ui/author/macro_in_loop.stdout index a719e3af7e76..3f9be297c33c 100644 --- a/tests/ui/author/macro_in_loop.stdout +++ b/tests/ui/author/macro_in_loop.stdout @@ -1,5 +1,5 @@ if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::ForLoop::hir(expr) - && let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = pat.kind + && let PatKind::Binding(BindingMode::NONE, _, name, None) = pat.kind && name.as_str() == "i" && let ExprKind::Struct(qpath, fields, None) = arg.kind && matches!(qpath, QPath::LangItem(LangItem::Range, _)) diff --git a/tests/ui/author/matches.stdout b/tests/ui/author/matches.stdout index 88e2ca656a4f..30e4a9b2560a 100644 --- a/tests/ui/author/matches.stdout +++ b/tests/ui/author/matches.stdout @@ -20,7 +20,7 @@ if let StmtKind::Local(local) = stmt.kind && let Some(init1) = local1.init && let ExprKind::Lit(ref lit4) = init1.kind && let LitKind::Int(3, LitIntType::Unsuffixed) = lit4.node - && let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local1.pat.kind + && let PatKind::Binding(BindingMode::NONE, _, name, None) = local1.pat.kind && name.as_str() == "x" && let Some(trailing_expr) = block.expr && let ExprKind::Path(ref qpath) = trailing_expr.kind @@ -29,7 +29,7 @@ if let StmtKind::Local(local) = stmt.kind && arms[2].guard.is_none() && let ExprKind::Lit(ref lit5) = arms[2].body.kind && let LitKind::Int(1, LitIntType::Unsuffixed) = lit5.node - && let PatKind::Binding(BindingAnnotation::NONE, _, name1, None) = local.pat.kind + && let PatKind::Binding(BindingMode::NONE, _, name1, None) = local.pat.kind && name1.as_str() == "a" { // report your lint here From 66362efb09bfaa8ee85a97b350d6c97174c0ad93 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Wed, 17 Apr 2024 14:40:00 +0000 Subject: [PATCH 010/279] Don't suggest `Box::default()` in functions with differing generics --- clippy_lints/src/box_default.rs | 4 ++-- tests/ui/box_default.fixed | 12 ++++++++++++ tests/ui/box_default.rs | 12 ++++++++++++ tests/ui/box_default.stderr | 8 +++++++- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/box_default.rs b/clippy_lints/src/box_default.rs index 4062212f408e..8459f051d3d9 100644 --- a/clippy_lints/src/box_default.rs +++ b/clippy_lints/src/box_default.rs @@ -121,9 +121,9 @@ fn given_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { if let Some(index) = args.iter().position(|arg| arg.hir_id == expr.hir_id) && let Some(sig) = expr_sig(cx, path) && let Some(input) = sig.input(index) - && !cx.typeck_results().expr_ty_adjusted(expr).boxed_ty().is_trait() + && let Some(input_ty) = input.no_bound_vars() { - input.no_bound_vars().is_some() + input_ty == cx.typeck_results().expr_ty_adjusted(expr) } else { false } diff --git a/tests/ui/box_default.fixed b/tests/ui/box_default.fixed index 6c2896b3aa0f..1f2f57c2507d 100644 --- a/tests/ui/box_default.fixed +++ b/tests/ui/box_default.fixed @@ -65,6 +65,8 @@ fn main() { // Would have a suggestion after https://github.com/rust-lang/rust/blob/fdd030127cc68afec44a8d3f6341525dd34e50ae/compiler/rustc_middle/src/ty/diagnostics.rs#L554-L563 let mut unnameable = Box::new(Option::default()); let _ = unnameable.insert(|| {}); + + let _ = Box::into_raw(Box::new(String::default())); } fn ret_ty_fn() -> Box { @@ -75,6 +77,16 @@ fn call_ty_fn(_b: Box) { issue_9621_dyn_trait(); } +struct X(T); + +impl X { + fn x(_: Box) {} + + fn same_generic_param() { + Self::x(Box::default()); + } +} + use std::io::{Read, Result}; impl Read for ImplementsDefault { diff --git a/tests/ui/box_default.rs b/tests/ui/box_default.rs index e19a62a90221..addfebc24f58 100644 --- a/tests/ui/box_default.rs +++ b/tests/ui/box_default.rs @@ -65,6 +65,8 @@ fn main() { // Would have a suggestion after https://github.com/rust-lang/rust/blob/fdd030127cc68afec44a8d3f6341525dd34e50ae/compiler/rustc_middle/src/ty/diagnostics.rs#L554-L563 let mut unnameable = Box::new(Option::default()); let _ = unnameable.insert(|| {}); + + let _ = Box::into_raw(Box::new(String::default())); } fn ret_ty_fn() -> Box { @@ -75,6 +77,16 @@ fn call_ty_fn(_b: Box) { issue_9621_dyn_trait(); } +struct X(T); + +impl X { + fn x(_: Box) {} + + fn same_generic_param() { + Self::x(Box::new(T::default())); + } +} + use std::io::{Read, Result}; impl Read for ImplementsDefault { diff --git a/tests/ui/box_default.stderr b/tests/ui/box_default.stderr index f172a875dce4..39fd0d29bbf9 100644 --- a/tests/ui/box_default.stderr +++ b/tests/ui/box_default.stderr @@ -55,5 +55,11 @@ error: `Box::new(_)` of default value LL | call_ty_fn(Box::new(u8::default())); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` -error: aborting due to 9 previous errors +error: `Box::new(_)` of default value + --> tests/ui/box_default.rs:86:17 + | +LL | Self::x(Box::new(T::default())); + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()` + +error: aborting due to 10 previous errors From 81106c5691bc05136a5ce679d94ac31b682769ed Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 15 Apr 2024 18:56:44 -0400 Subject: [PATCH 011/279] has_typeck_results doesnt need to be a query --- clippy_lints/src/functions/must_use.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs index d0c66900c006..e7ec2b3151e6 100644 --- a/clippy_lints/src/functions/must_use.rs +++ b/clippy_lints/src/functions/must_use.rs @@ -185,7 +185,7 @@ fn is_mutable_pat(cx: &LateContext<'_>, pat: &hir::Pat<'_>, tys: &mut DefIdSet) if let hir::PatKind::Wild = pat.kind { return false; // ignore `_` patterns } - if cx.tcx.has_typeck_results(pat.hir_id.owner.to_def_id()) { + if cx.tcx.has_typeck_results(pat.hir_id.owner.def_id) { is_mutable_ty(cx, cx.tcx.typeck(pat.hir_id.owner.def_id).pat_ty(pat), tys) } else { false @@ -233,7 +233,7 @@ fn mutates_static<'tcx>(cx: &LateContext<'tcx>, body: &'tcx hir::Body<'_>) -> bo Call(_, args) => { let mut tys = DefIdSet::default(); for arg in args { - if cx.tcx.has_typeck_results(arg.hir_id.owner.to_def_id()) + if cx.tcx.has_typeck_results(arg.hir_id.owner.def_id) && is_mutable_ty(cx, cx.tcx.typeck(arg.hir_id.owner.def_id).expr_ty(arg), &mut tys) && is_mutated_static(arg) { @@ -246,7 +246,7 @@ fn mutates_static<'tcx>(cx: &LateContext<'tcx>, body: &'tcx hir::Body<'_>) -> bo MethodCall(_, receiver, args, _) => { let mut tys = DefIdSet::default(); for arg in std::iter::once(receiver).chain(args.iter()) { - if cx.tcx.has_typeck_results(arg.hir_id.owner.to_def_id()) + if cx.tcx.has_typeck_results(arg.hir_id.owner.def_id) && is_mutable_ty(cx, cx.tcx.typeck(arg.hir_id.owner.def_id).expr_ty(arg), &mut tys) && is_mutated_static(arg) { From a5aaf33422f110d7a4ca6ba53fc5f2995dd6b0ce Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 18 Apr 2024 17:48:52 +0200 Subject: [PATCH 012/279] Merge commit 'ca3b393750ee8d870bf3215dcf6509cafa5c0445' into clippy-subtree-update --- .github/workflows/remark.yml | 2 +- CHANGELOG.md | 1 + book/src/README.md | 28 ++-- book/src/development/adding_lints.md | 26 +-- book/src/lint_configuration.md | 26 +++ clippy_config/src/conf.rs | 22 +++ clippy_dev/src/fmt.rs | 1 - clippy_dev/src/lib.rs | 1 + clippy_dev/src/main.rs | 55 +++++-- clippy_dev/src/new_lint.rs | 1 - clippy_dev/src/setup/mod.rs | 1 + clippy_dev/src/setup/toolchain.rs | 75 +++++++++ clippy_lints/src/arc_with_non_send_sync.rs | 26 ++- .../src/attrs/duplicated_attributes.rs | 8 +- clippy_lints/src/attrs/mod.rs | 11 +- clippy_lints/src/booleans.rs | 17 +- clippy_lints/src/casts/mod.rs | 10 +- clippy_lints/src/dereference.rs | 9 ++ clippy_lints/src/derive.rs | 2 +- clippy_lints/src/doc/missing_headers.rs | 2 +- clippy_lints/src/doc/mod.rs | 151 +++++++----------- clippy_lints/src/index_refutable_slice.rs | 2 +- clippy_lints/src/item_name_repetitions.rs | 12 +- clippy_lints/src/legacy_numeric_constants.rs | 2 +- clippy_lints/src/lib.rs | 2 + clippy_lints/src/lifetimes.rs | 5 +- clippy_lints/src/manual_unwrap_or_default.rs | 95 +++++------ clippy_lints/src/methods/mod.rs | 1 - clippy_lints/src/methods/search_is_some.rs | 38 ++++- .../src/needless_borrows_for_generic_args.rs | 2 +- clippy_lints/src/non_copy_const.rs | 9 +- clippy_lints/src/strings.rs | 7 +- .../transmute/transmute_int_to_non_zero.rs | 4 +- .../transmutes_expressible_as_ptr_casts.rs | 2 +- clippy_utils/src/ast_utils.rs | 8 +- clippy_utils/src/lib.rs | 2 +- clippy_utils/src/ty.rs | 2 +- clippy_utils/src/ty/type_certainty/mod.rs | 2 +- lintcheck/src/main.rs | 96 +++++++---- rust-toolchain | 2 +- tests/ui-internal/custom_ice_message.rs | 1 - tests/ui-internal/custom_ice_message.stderr | 7 +- .../allowed_prefixes/clippy.toml | 1 + .../allowed_prefixes/item_name_repetitions.rs | 15 ++ .../item_name_repetitions.stderr | 11 ++ .../allowed_prefixes_extend/clippy.toml | 1 + .../item_name_repetitions.rs | 21 +++ .../item_name_repetitions.stderr | 11 ++ .../toml_unknown_key/conf_unknown_key.stderr | 3 + tests/ui/arc_with_non_send_sync.rs | 7 - tests/ui/arc_with_non_send_sync.stderr | 29 ++-- tests/ui/auxiliary/proc_macro_attr.rs | 14 ++ tests/ui/cast.rs | 12 ++ tests/ui/cast.stderr | 45 +++++- tests/ui/crashes/ice-12585.rs | 26 +++ tests/ui/crashes/ice-12616.stderr | 10 +- tests/ui/doc/doc-fixable.fixed | 5 + tests/ui/doc/doc-fixable.rs | 5 + tests/ui/doc/doc-fixable.stderr | 13 +- tests/ui/duplicated_attributes.rs | 10 +- tests/ui/duplicated_attributes.stderr | 31 +--- tests/ui/manual_unwrap_or_default.fixed | 10 ++ tests/ui/manual_unwrap_or_default.rs | 10 ++ tests/ui/manual_unwrap_or_default.stderr | 2 +- tests/ui/module_name_repetitions.rs | 14 ++ tests/ui/multiple_unsafe_ops_per_block.rs | 1 + tests/ui/multiple_unsafe_ops_per_block.stderr | 58 +++---- tests/ui/needless_borrow.fixed | 8 + tests/ui/needless_borrow.rs | 8 + tests/ui/needless_borrow.stderr | 8 +- tests/ui/nonminimal_bool_methods.fixed | 8 + tests/ui/nonminimal_bool_methods.rs | 8 + tests/ui/nonminimal_bool_methods.stderr | 20 ++- tests/ui/ptr_as_ptr.fixed | 1 - tests/ui/ptr_as_ptr.rs | 1 - tests/ui/ptr_as_ptr.stderr | 66 ++++---- tests/ui/search_is_some_fixable_none.fixed | 50 ++++++ tests/ui/search_is_some_fixable_none.rs | 50 ++++++ tests/ui/search_is_some_fixable_none.stderr | 74 ++++++++- tests/ui/unconditional_recursion.rs | 2 +- tests/ui/unnecessary_clippy_cfg.stderr | 38 ++++- tests/ui/useless_attribute.fixed | 2 +- tests/ui/useless_attribute.rs | 2 +- triagebot.toml | 7 +- 84 files changed, 1067 insertions(+), 427 deletions(-) create mode 100644 clippy_dev/src/setup/toolchain.rs create mode 100644 tests/ui-toml/item_name_repetitions/allowed_prefixes/clippy.toml create mode 100644 tests/ui-toml/item_name_repetitions/allowed_prefixes/item_name_repetitions.rs create mode 100644 tests/ui-toml/item_name_repetitions/allowed_prefixes/item_name_repetitions.stderr create mode 100644 tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/clippy.toml create mode 100644 tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/item_name_repetitions.rs create mode 100644 tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/item_name_repetitions.stderr create mode 100644 tests/ui/crashes/ice-12585.rs diff --git a/.github/workflows/remark.yml b/.github/workflows/remark.yml index 05e1b3b9202b..348d52020fd2 100644 --- a/.github/workflows/remark.yml +++ b/.github/workflows/remark.yml @@ -24,7 +24,7 @@ jobs: node-version: '18.x' - name: Install remark - run: npm install remark-cli remark-lint remark-lint-maximum-line-length remark-preset-lint-recommended remark-gfm + run: npm install remark-cli remark-lint remark-lint-maximum-line-length@^3.1.3 remark-preset-lint-recommended remark-gfm - name: Install mdbook run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index f7e7ed86eed8..bd3a04e34ae3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5894,6 +5894,7 @@ Released 2018-09-13 [`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles [`allowed-duplicate-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-duplicate-crates [`allowed-idents-below-min-chars`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-idents-below-min-chars +[`allowed-prefixes`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-prefixes [`allowed-scripts`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-scripts [`allowed-wildcard-imports`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-wildcard-imports [`arithmetic-side-effects-allowed`]: https://doc.rust-lang.org/clippy/lint_configuration.html#arithmetic-side-effects-allowed diff --git a/book/src/README.md b/book/src/README.md index e7972b0db19c..7bdfb97c3acf 100644 --- a/book/src/README.md +++ b/book/src/README.md @@ -18,17 +18,27 @@ category. | `clippy::all` | all lints that are on by default (correctness, suspicious, style, complexity, perf) | **warn/deny** | | `clippy::correctness` | code that is outright wrong or useless | **deny** | | `clippy::suspicious` | code that is most likely wrong or useless | **warn** | +| `clippy::style` | code that should be written in a more idiomatic way | **warn** | | `clippy::complexity` | code that does something simple but in a complex way | **warn** | | `clippy::perf` | code that can be written to run faster | **warn** | -| `clippy::style` | code that should be written in a more idiomatic way | **warn** | -| `clippy::pedantic` | lints which are rather strict or might have false positives | allow | +| `clippy::pedantic` | lints which are rather strict or have occasional false positives | allow | +| `clippy::restriction` | lints which prevent the use of language and library features[^restrict] | allow | | `clippy::nursery` | new lints that are still under development | allow | -| `clippy::cargo` | lints for the cargo manifest | allow | | allow | +| `clippy::cargo` | lints for the cargo manifest | allow | -More to come, please [file an -issue](https://github.com/rust-lang/rust-clippy/issues) if you have ideas! +More to come, please [file an issue](https://github.com/rust-lang/rust-clippy/issues) if you have ideas! -The [lint list](https://rust-lang.github.io/rust-clippy/master/index.html) also -contains "restriction lints", which are for things which are usually not -considered "bad", but may be useful to turn on in specific cases. These should -be used very selectively, if at all. +The `restriction` category should, *emphatically*, not be enabled as a whole. The contained +lints may lint against perfectly reasonable code, may not have an alternative suggestion, +and may contradict any other lints (including other categories). Lints should be considered +on a case-by-case basis before enabling. + +[^restrict]: Some use cases for `restriction` lints include: + - Strict coding styles (e.g. [`clippy::else_if_without_else`]). + - Additional restrictions on CI (e.g. [`clippy::todo`]). + - Preventing panicking in certain functions (e.g. [`clippy::unwrap_used`]). + - Running a lint only on a subset of code (e.g. `#[forbid(clippy::float_arithmetic)]` on a module). + +[`clippy::else_if_without_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#else_if_without_else +[`clippy::todo`]: https://rust-lang.github.io/rust-clippy/master/index.html#todo +[`clippy::unwrap_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used diff --git a/book/src/development/adding_lints.md b/book/src/development/adding_lints.md index e30a5f9fe10b..b80ac6370e7a 100644 --- a/book/src/development/adding_lints.md +++ b/book/src/development/adding_lints.md @@ -18,7 +18,6 @@ because that's clearly a non-descriptive name. - [Cargo lints](#cargo-lints) - [Rustfix tests](#rustfix-tests) - [Testing manually](#testing-manually) - - [Running directly](#running-directly) - [Lint declaration](#lint-declaration) - [Lint registration](#lint-registration) - [Lint passes](#lint-passes) @@ -176,23 +175,26 @@ the tests. Manually testing against an example file can be useful if you have added some `println!`s and the test suite output becomes unreadable. To try Clippy with -your local modifications, run +your local modifications, run the following from the Clippy directory: -``` +```bash cargo dev lint input.rs ``` -from the working copy root. With tests in place, let's have a look at -implementing our lint now. +To run Clippy on an existing project rather than a single file you can use -## Running directly +```bash +cargo dev lint /path/to/project +``` -While it's easier to just use `cargo dev lint`, it might be desirable to get -`target/release/cargo-clippy` and `target/release/clippy-driver` to work as well in some cases. -By default, they don't work because clippy dynamically links rustc. To help them find rustc, -add the path printed by`rustc --print target-libdir` (ran inside this workspace so that the rustc version matches) -to your library search path. -On linux, this can be done by setting the `LD_LIBRARY_PATH` environment variable to that path. +Or set up a rustup toolchain that points to the local Clippy binaries + +```bash +cargo dev setup toolchain + +# Then in `/path/to/project` you can run +cargo +clippy clippy +``` ## Lint declaration diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 4a2727c5197f..7cefa6852642 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -164,6 +164,32 @@ configuration of Clippy. By default, any configuration will replace the default * [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars) +## `allowed-prefixes` +List of prefixes to allow when determining whether an item's name ends with the module's name. +If the rest of an item's name is an allowed prefix (e.g. item `ToFoo` or `to_foo` in module `foo`), +then don't emit a warning. + +#### Example + +```toml +allowed-prefixes = [ "to", "from" ] +``` + +#### Noteworthy + +- By default, the following prefixes are allowed: `to`, `as`, `into`, `from`, `try_into` and `try_from` +- PascalCase variant is included automatically for each snake_case variant (e.g. if `try_into` is included, + `TryInto` will also be included) +- Use `".."` as part of the list to indicate that the configured values should be appended to the +default configuration of Clippy. By default, any configuration will replace the default value + +**Default Value:** `["to", "as", "into", "from", "try_into", "try_from"]` + +--- +**Affected lints:** +* [`module_name_repetitions`](https://rust-lang.github.io/rust-clippy/master/index.html#module_name_repetitions) + + ## `allowed-scripts` The list of unicode scripts allowed to be used in the scope. diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 53c10f7cee8b..781282213cc4 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -39,6 +39,7 @@ const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[ ]; const DEFAULT_DISALLOWED_NAMES: &[&str] = &["foo", "baz", "quux"]; const DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS: &[&str] = &["i", "j", "x", "y", "z", "w", "n"]; +const DEFAULT_ALLOWED_PREFIXES: &[&str] = &["to", "as", "into", "from", "try_into", "try_from"]; /// Conf with parse errors #[derive(Default)] @@ -589,6 +590,26 @@ define_Conf! { /// 2. Paths with any segment that containing the word 'prelude' /// are already allowed by default. (allowed_wildcard_imports: FxHashSet = FxHashSet::default()), + /// Lint: MODULE_NAME_REPETITIONS. + /// + /// List of prefixes to allow when determining whether an item's name ends with the module's name. + /// If the rest of an item's name is an allowed prefix (e.g. item `ToFoo` or `to_foo` in module `foo`), + /// then don't emit a warning. + /// + /// #### Example + /// + /// ```toml + /// allowed-prefixes = [ "to", "from" ] + /// ``` + /// + /// #### Noteworthy + /// + /// - By default, the following prefixes are allowed: `to`, `as`, `into`, `from`, `try_into` and `try_from` + /// - PascalCase variant is included automatically for each snake_case variant (e.g. if `try_into` is included, + /// `TryInto` will also be included) + /// - Use `".."` as part of the list to indicate that the configured values should be appended to the + /// default configuration of Clippy. By default, any configuration will replace the default value + (allowed_prefixes: Vec = DEFAULT_ALLOWED_PREFIXES.iter().map(ToString::to_string).collect()), } /// Search for the configuration file. @@ -649,6 +670,7 @@ fn deserialize(file: &SourceFile) -> TryConf { Ok(mut conf) => { extend_vec_if_indicator_present(&mut conf.conf.doc_valid_idents, DEFAULT_DOC_VALID_IDENTS); extend_vec_if_indicator_present(&mut conf.conf.disallowed_names, DEFAULT_DISALLOWED_NAMES); + extend_vec_if_indicator_present(&mut conf.conf.allowed_prefixes, DEFAULT_ALLOWED_PREFIXES); // TODO: THIS SHOULD BE TESTED, this comment will be gone soon if conf.conf.allowed_idents_below_min_chars.contains("..") { conf.conf diff --git a/clippy_dev/src/fmt.rs b/clippy_dev/src/fmt.rs index ee559d45dd16..256231441817 100644 --- a/clippy_dev/src/fmt.rs +++ b/clippy_dev/src/fmt.rs @@ -35,7 +35,6 @@ struct FmtContext { } // the "main" function of cargo dev fmt -#[allow(clippy::missing_panics_doc)] pub fn run(check: bool, verbose: bool) { fn try_run(context: &FmtContext) -> Result { let mut success = true; diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs index bb62e902cd54..385191e0361b 100644 --- a/clippy_dev/src/lib.rs +++ b/clippy_dev/src/lib.rs @@ -9,6 +9,7 @@ unused_lifetimes, unused_qualifications )] +#![allow(clippy::missing_panics_doc)] // The `rustc_driver` crate seems to be required in order to use the `rust_lexer` crate. #[allow(unused_extern_crates)] diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs index 5bd9994e18d5..397a0e990829 100644 --- a/clippy_dev/src/main.rs +++ b/clippy_dev/src/main.rs @@ -46,6 +46,13 @@ fn main() { } }, Some(("setup", sub_command)) => match sub_command.subcommand() { + Some(("git-hook", matches)) => { + if matches.get_flag("remove") { + setup::git_hook::remove_hook(); + } else { + setup::git_hook::install_hook(matches.get_flag("force-override")); + } + }, Some(("intellij", matches)) => { if matches.get_flag("remove") { setup::intellij::remove_rustc_src(); @@ -57,12 +64,12 @@ fn main() { ); } }, - Some(("git-hook", matches)) => { - if matches.get_flag("remove") { - setup::git_hook::remove_hook(); - } else { - setup::git_hook::install_hook(matches.get_flag("force-override")); - } + Some(("toolchain", matches)) => { + setup::toolchain::create( + matches.get_flag("force"), + matches.get_flag("release"), + matches.get_one::("name").unwrap(), + ); }, Some(("vscode-tasks", matches)) => { if matches.get_flag("remove") { @@ -210,6 +217,19 @@ fn get_clap_config() -> ArgMatches { .about("Support for setting up your personal development environment") .arg_required_else_help(true) .subcommands([ + Command::new("git-hook") + .about("Add a pre-commit git hook that formats your code to make it look pretty") + .args([ + Arg::new("remove") + .long("remove") + .action(ArgAction::SetTrue) + .help("Remove the pre-commit hook added with 'cargo dev setup git-hook'"), + Arg::new("force-override") + .long("force-override") + .short('f') + .action(ArgAction::SetTrue) + .help("Forces the override of an existing git pre-commit hook"), + ]), Command::new("intellij") .about("Alter dependencies so Intellij Rust can find rustc internals") .args([ @@ -225,18 +245,23 @@ fn get_clap_config() -> ArgMatches { .conflicts_with("remove") .required(true), ]), - Command::new("git-hook") - .about("Add a pre-commit git hook that formats your code to make it look pretty") + Command::new("toolchain") + .about("Install a rustup toolchain pointing to the local clippy build") .args([ - Arg::new("remove") - .long("remove") - .action(ArgAction::SetTrue) - .help("Remove the pre-commit hook added with 'cargo dev setup git-hook'"), - Arg::new("force-override") - .long("force-override") + Arg::new("force") + .long("force") .short('f') .action(ArgAction::SetTrue) - .help("Forces the override of an existing git pre-commit hook"), + .help("Override an existing toolchain"), + Arg::new("release") + .long("release") + .short('r') + .action(ArgAction::SetTrue) + .help("Point to --release clippy binaries"), + Arg::new("name") + .long("name") + .default_value("clippy") + .help("The name of the created toolchain"), ]), Command::new("vscode-tasks") .about("Add several tasks to vscode for formatting, validation and testing") diff --git a/clippy_dev/src/new_lint.rs b/clippy_dev/src/new_lint.rs index 5d9cde06cd86..2940d56350f4 100644 --- a/clippy_dev/src/new_lint.rs +++ b/clippy_dev/src/new_lint.rs @@ -36,7 +36,6 @@ impl Context for io::Result { /// # Errors /// /// This function errors out if the files couldn't be created or written to. -#[allow(clippy::missing_panics_doc)] pub fn create( pass: &String, lint_name: Option<&String>, diff --git a/clippy_dev/src/setup/mod.rs b/clippy_dev/src/setup/mod.rs index f691ae4fa45d..b0d318146391 100644 --- a/clippy_dev/src/setup/mod.rs +++ b/clippy_dev/src/setup/mod.rs @@ -1,5 +1,6 @@ pub mod git_hook; pub mod intellij; +pub mod toolchain; pub mod vscode; use std::path::Path; diff --git a/clippy_dev/src/setup/toolchain.rs b/clippy_dev/src/setup/toolchain.rs new file mode 100644 index 000000000000..8d98c6c92d9d --- /dev/null +++ b/clippy_dev/src/setup/toolchain.rs @@ -0,0 +1,75 @@ +use std::env::consts::EXE_SUFFIX; +use std::env::current_dir; +use std::ffi::OsStr; +use std::fs; +use std::path::{Path, PathBuf}; +use walkdir::WalkDir; + +use super::verify_inside_clippy_dir; + +pub fn create(force: bool, release: bool, name: &str) { + if !verify_inside_clippy_dir() { + return; + } + + let rustup_home = std::env::var("RUSTUP_HOME").unwrap(); + let toolchain = std::env::var("RUSTUP_TOOLCHAIN").unwrap(); + + let src = PathBuf::from_iter([&rustup_home, "toolchains", &toolchain]); + let dest = PathBuf::from_iter([&rustup_home, "toolchains", name]); + + if dest.exists() { + if force { + fs::remove_dir_all(&dest).unwrap(); + } else { + println!("{} already exists, pass `--force` to override it", dest.display()); + return; + } + } + + for entry in WalkDir::new(&src) { + let entry = entry.unwrap(); + let relative = entry.path().strip_prefix(&src).unwrap(); + + if relative.starts_with("bin") + && matches!( + relative.file_stem().and_then(OsStr::to_str), + Some("cargo-clippy" | "clippy-driver") + ) + { + continue; + } + + let target = dest.join(relative); + if entry.file_type().is_dir() { + fs::create_dir(&target).unwrap(); + } else { + fs::hard_link(entry.path(), target).unwrap(); + } + } + + symlink_bin("cargo-clippy", &dest, release); + symlink_bin("clippy-driver", &dest, release); + + println!("Created toolchain {name}, use it in other projects with e.g. `cargo +{name} clippy`"); + println!("Note: This will need to be re-run whenever the Clippy `rust-toolchain` changes"); +} + +fn symlink_bin(bin: &str, dest: &Path, release: bool) { + #[cfg(windows)] + use std::os::windows::fs::symlink_file as symlink; + + #[cfg(not(windows))] + use std::os::unix::fs::symlink; + + let profile = if release { "release" } else { "debug" }; + let file_name = format!("{bin}{EXE_SUFFIX}"); + + let mut src = current_dir().unwrap(); + src.extend(["target", profile, &file_name]); + + let mut dest = dest.to_path_buf(); + dest.extend(["bin", &file_name]); + + symlink(src, dest).unwrap(); +} diff --git a/clippy_lints/src/arc_with_non_send_sync.rs b/clippy_lints/src/arc_with_non_send_sync.rs index 1102c7fb236b..389338973894 100644 --- a/clippy_lints/src/arc_with_non_send_sync.rs +++ b/clippy_lints/src/arc_with_non_send_sync.rs @@ -56,7 +56,12 @@ impl<'tcx> LateLintPass<'tcx> for ArcWithNonSendSync { && let Some(send) = cx.tcx.get_diagnostic_item(sym::Send) && let Some(sync) = cx.tcx.lang_items().sync_trait() && let [is_send, is_sync] = [send, sync].map(|id| implements_trait(cx, arg_ty, id, &[])) - && !(is_send && is_sync) + && let reason = match (is_send, is_sync) { + (false, false) => "neither `Send` nor `Sync`", + (false, true) => "not `Send`", + (true, false) => "not `Sync`", + _ => return, + } && !is_from_proc_macro(cx, expr) { span_lint_and_then( @@ -66,21 +71,12 @@ impl<'tcx> LateLintPass<'tcx> for ArcWithNonSendSync { "usage of an `Arc` that is not `Send` and `Sync`", |diag| { with_forced_trimmed_paths!({ - diag.note(format!("`Arc<{arg_ty}>` is not `Send` and `Sync` as:")); - - if !is_send { - diag.note(format!("- the trait `Send` is not implemented for `{arg_ty}`")); - } - if !is_sync { - diag.note(format!("- the trait `Sync` is not implemented for `{arg_ty}`")); - } - - diag.help("consider using an `Rc` instead. `Arc` does not provide benefits for non `Send` and `Sync` types"); - - diag.note("if you intend to use `Arc` with `Send` and `Sync` traits"); - diag.note(format!( - "wrap the inner type with a `Mutex` or implement `Send` and `Sync` for `{arg_ty}`" + "`Arc<{arg_ty}>` is not `Send` and `Sync` as `{arg_ty}` is {reason}" + )); + diag.help("if the `Arc` will not used be across threads replace it with an `Rc`"); + diag.help(format!( + "otherwise make `{arg_ty}` `Send` and `Sync` or consider a wrapper type such as `Mutex`" )); }); }, diff --git a/clippy_lints/src/attrs/duplicated_attributes.rs b/clippy_lints/src/attrs/duplicated_attributes.rs index 3a8844d07548..736ee48641d8 100644 --- a/clippy_lints/src/attrs/duplicated_attributes.rs +++ b/clippy_lints/src/attrs/duplicated_attributes.rs @@ -2,12 +2,12 @@ use super::DUPLICATED_ATTRIBUTES; use clippy_utils::diagnostics::span_lint_and_then; use rustc_ast::{Attribute, MetaItem}; use rustc_data_structures::fx::FxHashMap; -use rustc_lint::EarlyContext; +use rustc_lint::LateContext; use rustc_span::{sym, Span}; use std::collections::hash_map::Entry; fn emit_if_duplicated( - cx: &EarlyContext<'_>, + cx: &LateContext<'_>, attr: &MetaItem, attr_paths: &mut FxHashMap, complete_path: String, @@ -26,7 +26,7 @@ fn emit_if_duplicated( } fn check_duplicated_attr( - cx: &EarlyContext<'_>, + cx: &LateContext<'_>, attr: &MetaItem, attr_paths: &mut FxHashMap, parent: &mut Vec, @@ -64,7 +64,7 @@ fn check_duplicated_attr( } } -pub fn check(cx: &EarlyContext<'_>, attrs: &[Attribute]) { +pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) { let mut attr_paths = FxHashMap::default(); for attr in attrs { diff --git a/clippy_lints/src/attrs/mod.rs b/clippy_lints/src/attrs/mod.rs index 684ad7de2f05..8f47bc7653b7 100644 --- a/clippy_lints/src/attrs/mod.rs +++ b/clippy_lints/src/attrs/mod.rs @@ -17,7 +17,7 @@ mod useless_attribute; mod utils; use clippy_config::msrvs::Msrv; -use rustc_ast::{Attribute, Crate, MetaItemKind, NestedMetaItem}; +use rustc_ast::{Attribute, MetaItemKind, NestedMetaItem}; use rustc_hir::{ImplItem, Item, ItemKind, TraitItem}; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, impl_lint_pass}; @@ -534,11 +534,13 @@ declare_lint_pass!(Attributes => [ BLANKET_CLIPPY_RESTRICTION_LINTS, SHOULD_PANIC_WITHOUT_EXPECT, MIXED_ATTRIBUTES_STYLE, + DUPLICATED_ATTRIBUTES, ]); impl<'tcx> LateLintPass<'tcx> for Attributes { fn check_crate(&mut self, cx: &LateContext<'tcx>) { blanket_clippy_restriction_lints::check_command_line(cx); + duplicated_attributes::check(cx, cx.tcx.hir().krate_attrs()); } fn check_attribute(&mut self, cx: &LateContext<'tcx>, attr: &'tcx Attribute) { @@ -578,6 +580,7 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { _ => {}, } mixed_attributes_style::check(cx, item.span, attrs); + duplicated_attributes::check(cx, attrs); } fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { @@ -606,17 +609,11 @@ impl_lint_pass!(EarlyAttributes => [ MAYBE_MISUSED_CFG, DEPRECATED_CLIPPY_CFG_ATTR, UNNECESSARY_CLIPPY_CFG, - DUPLICATED_ATTRIBUTES, ]); impl EarlyLintPass for EarlyAttributes { - fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &Crate) { - duplicated_attributes::check(cx, &krate.attrs); - } - fn check_item(&mut self, cx: &EarlyContext<'_>, item: &rustc_ast::Item) { empty_line_after::check(cx, item); - duplicated_attributes::check(cx, &item.attrs); } fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) { diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index 6edfebb5534f..b6341b3fe8e7 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -346,11 +346,18 @@ fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { _ => None, } .and_then(|op| { - Some(format!( - "{}{op}{}", - snippet_opt(cx, lhs.span)?, - snippet_opt(cx, rhs.span)? - )) + let lhs_snippet = snippet_opt(cx, lhs.span)?; + let rhs_snippet = snippet_opt(cx, rhs.span)?; + + if !(lhs_snippet.starts_with('(') && lhs_snippet.ends_with(')')) { + if let (ExprKind::Cast(..), BinOpKind::Ge) = (&lhs.kind, binop.node) { + // e.g. `(a as u64) < b`. Without the parens the `<` is + // interpreted as a start of generic arguments for `u64` + return Some(format!("({lhs_snippet}){op}{rhs_snippet}")); + } + } + + Some(format!("{lhs_snippet}{op}{rhs_snippet}")) }) }, ExprKind::MethodCall(path, receiver, [], _) => { diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index 063aab282384..d14898a8196c 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -754,11 +754,7 @@ impl_lint_pass!(Casts => [ impl<'tcx> LateLintPass<'tcx> for Casts { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if !in_external_macro(cx.sess(), expr.span) { - ptr_as_ptr::check(cx, expr, &self.msrv); - } - - if expr.span.from_expansion() { + if in_external_macro(cx.sess(), expr.span) { return; } @@ -771,7 +767,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts { cx.typeck_results().expr_ty(expr), ); - if unnecessary_cast::check(cx, expr, cast_expr, cast_from, cast_to) { + if !expr.span.from_expansion() && unnecessary_cast::check(cx, expr, cast_expr, cast_from, cast_to) { return; } cast_slice_from_raw_parts::check(cx, expr, cast_expr, cast_to, &self.msrv); @@ -782,7 +778,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts { fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to); zero_ptr::check(cx, expr, cast_expr, cast_to_hir); - if cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) { + if cast_to.is_numeric() { cast_possible_truncation::check(cx, expr, cast_expr, cast_from, cast_to, cast_to_hir.span); if cast_from.is_numeric() { cast_possible_wrap::check(cx, expr, cast_from, cast_to); diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index bff40c2ae75d..89e2b3449680 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -1016,9 +1016,18 @@ fn report<'tcx>( }, _ => (0, false), }; + let is_in_tuple = matches!( + get_parent_expr(cx, data.first_expr), + Some(Expr { + kind: ExprKind::Tup(..), + .. + }) + ); + let sugg = if !snip_is_macro && (calls_field || expr.precedence().order() < precedence) && !has_enclosing_paren(&snip) + && !is_in_tuple { format!("({snip})") } else { diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index 5f9700b76d94..42cd19fb8eca 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -132,7 +132,7 @@ declare_clippy_lint! { /// /// ### Why is this bad? /// Deriving `serde::Deserialize` will create a constructor - /// that may violate invariants hold by another constructor. + /// that may violate invariants held by another constructor. /// /// ### Example /// ```rust,ignore diff --git a/clippy_lints/src/doc/missing_headers.rs b/clippy_lints/src/doc/missing_headers.rs index 26f120cb33f0..f935ae2e3e48 100644 --- a/clippy_lints/src/doc/missing_headers.rs +++ b/clippy_lints/src/doc/missing_headers.rs @@ -11,7 +11,7 @@ use super::{DocHeaders, MISSING_ERRORS_DOC, MISSING_PANICS_DOC, MISSING_SAFETY_D pub fn check( cx: &LateContext<'_>, owner_id: OwnerId, - sig: &FnSig<'_>, + sig: FnSig<'_>, headers: DocHeaders, body_id: Option, panic_span: Option, diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index b135e4e35771..4bced104d3bc 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -3,7 +3,7 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_help}; use clippy_utils::macros::{is_panic, root_macro_call_first_node}; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::visitors::Visitable; -use clippy_utils::{is_entrypoint_fn, method_chain_args}; +use clippy_utils::{is_entrypoint_fn, is_trait_impl_item, method_chain_args}; use pulldown_cmark::Event::{ Code, End, FootnoteReference, HardBreak, Html, Rule, SoftBreak, Start, TaskListMarker, Text, }; @@ -11,9 +11,8 @@ use pulldown_cmark::Tag::{BlockQuote, CodeBlock, Heading, Item, Link, Paragraph} use pulldown_cmark::{BrokenLink, CodeBlockKind, CowStr, Options}; use rustc_ast::ast::Attribute; use rustc_data_structures::fx::FxHashSet; -use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{AnonConst, Expr}; +use rustc_hir::{AnonConst, Expr, ImplItemKind, ItemKind, Node, TraitItemKind, Unsafety}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::nested_filter; use rustc_middle::lint::in_external_macro; @@ -366,7 +365,6 @@ declare_clippy_lint! { #[derive(Clone)] pub struct Documentation { valid_idents: FxHashSet, - in_trait_impl: bool, check_private_items: bool, } @@ -374,7 +372,6 @@ impl Documentation { pub fn new(valid_idents: &[String], check_private_items: bool) -> Self { Self { valid_idents: valid_idents.iter().cloned().collect(), - in_trait_impl: false, check_private_items, } } @@ -394,36 +391,72 @@ impl_lint_pass!(Documentation => [ ]); impl<'tcx> LateLintPass<'tcx> for Documentation { - fn check_crate(&mut self, cx: &LateContext<'tcx>) { - let attrs = cx.tcx.hir().attrs(hir::CRATE_HIR_ID); - check_attrs(cx, &self.valid_idents, attrs); - } - - fn check_variant(&mut self, cx: &LateContext<'tcx>, variant: &'tcx hir::Variant<'tcx>) { - let attrs = cx.tcx.hir().attrs(variant.hir_id); - check_attrs(cx, &self.valid_idents, attrs); - } - - fn check_field_def(&mut self, cx: &LateContext<'tcx>, variant: &'tcx hir::FieldDef<'tcx>) { - let attrs = cx.tcx.hir().attrs(variant.hir_id); - check_attrs(cx, &self.valid_idents, attrs); - } - - fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + fn check_attributes(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) { let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return; }; - match item.kind { - hir::ItemKind::Fn(ref sig, _, body_id) => { - if !(is_entrypoint_fn(cx, item.owner_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)) { - let body = cx.tcx.hir().body(body_id); + match cx.tcx.hir_node(cx.last_node_with_lint_attrs) { + Node::Item(item) => match item.kind { + ItemKind::Fn(sig, _, body_id) => { + if !(is_entrypoint_fn(cx, item.owner_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)) { + let body = cx.tcx.hir().body(body_id); - let panic_span = FindPanicUnwrap::find_span(cx, cx.tcx.typeck(item.owner_id), body.value); + let panic_span = FindPanicUnwrap::find_span(cx, cx.tcx.typeck(item.owner_id), body.value); + missing_headers::check( + cx, + item.owner_id, + sig, + headers, + Some(body_id), + panic_span, + self.check_private_items, + ); + } + }, + ItemKind::Trait(_, unsafety, ..) => match (headers.safety, unsafety) { + (false, Unsafety::Unsafe) => span_lint( + cx, + MISSING_SAFETY_DOC, + cx.tcx.def_span(item.owner_id), + "docs for unsafe trait missing `# Safety` section", + ), + (true, Unsafety::Normal) => span_lint( + cx, + UNNECESSARY_SAFETY_DOC, + cx.tcx.def_span(item.owner_id), + "docs for safe trait have unnecessary `# Safety` section", + ), + _ => (), + }, + _ => (), + }, + Node::TraitItem(trait_item) => { + if let TraitItemKind::Fn(sig, ..) = trait_item.kind + && !in_external_macro(cx.tcx.sess, trait_item.span) + { missing_headers::check( cx, - item.owner_id, + trait_item.owner_id, + sig, + headers, + None, + None, + self.check_private_items, + ); + } + }, + Node::ImplItem(impl_item) => { + if let ImplItemKind::Fn(sig, body_id) = impl_item.kind + && !in_external_macro(cx.tcx.sess, impl_item.span) + && !is_trait_impl_item(cx, impl_item.hir_id()) + { + let body = cx.tcx.hir().body(body_id); + + let panic_span = FindPanicUnwrap::find_span(cx, cx.tcx.typeck(impl_item.owner_id), body.value); + missing_headers::check( + cx, + impl_item.owner_id, sig, headers, Some(body_id), @@ -432,67 +465,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation { ); } }, - hir::ItemKind::Impl(impl_) => { - self.in_trait_impl = impl_.of_trait.is_some(); - }, - hir::ItemKind::Trait(_, unsafety, ..) => match (headers.safety, unsafety) { - (false, hir::Unsafety::Unsafe) => span_lint( - cx, - MISSING_SAFETY_DOC, - cx.tcx.def_span(item.owner_id), - "docs for unsafe trait missing `# Safety` section", - ), - (true, hir::Unsafety::Normal) => span_lint( - cx, - UNNECESSARY_SAFETY_DOC, - cx.tcx.def_span(item.owner_id), - "docs for safe trait have unnecessary `# Safety` section", - ), - _ => (), - }, - _ => (), - } - } - - fn check_item_post(&mut self, _cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { - if let hir::ItemKind::Impl { .. } = item.kind { - self.in_trait_impl = false; - } - } - - fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) { - let attrs = cx.tcx.hir().attrs(item.hir_id()); - let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { - return; - }; - if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind { - if !in_external_macro(cx.tcx.sess, item.span) { - missing_headers::check(cx, item.owner_id, sig, headers, None, None, self.check_private_items); - } - } - } - - fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) { - let attrs = cx.tcx.hir().attrs(item.hir_id()); - let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { - return; - }; - if self.in_trait_impl || in_external_macro(cx.tcx.sess, item.span) { - return; - } - if let hir::ImplItemKind::Fn(ref sig, body_id) = item.kind { - let body = cx.tcx.hir().body(body_id); - - let panic_span = FindPanicUnwrap::find_span(cx, cx.tcx.typeck(item.owner_id), body.value); - missing_headers::check( - cx, - item.owner_id, - sig, - headers, - Some(body_id), - panic_span, - self.check_private_items, - ); + _ => {}, } } } diff --git a/clippy_lints/src/index_refutable_slice.rs b/clippy_lints/src/index_refutable_slice.rs index 799ec9d553d4..a4c3b06046e8 100644 --- a/clippy_lints/src/index_refutable_slice.rs +++ b/clippy_lints/src/index_refutable_slice.rs @@ -7,8 +7,8 @@ use clippy_utils::{is_expn_of, is_lint_allowed, path_to_local}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::Applicability; use rustc_hir as hir; -use rustc_hir::HirId; use rustc_hir::intravisit::{self, Visitor}; +use rustc_hir::HirId; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::ty; diff --git a/clippy_lints/src/item_name_repetitions.rs b/clippy_lints/src/item_name_repetitions.rs index 6615122567dc..33764d3eb094 100644 --- a/clippy_lints/src/item_name_repetitions.rs +++ b/clippy_lints/src/item_name_repetitions.rs @@ -5,6 +5,7 @@ use clippy_utils::is_bool; use clippy_utils::macros::span_is_local; use clippy_utils::source::is_present_in_source; use clippy_utils::str_utils::{camel_case_split, count_match_end, count_match_start, to_camel_case, to_snake_case}; +use rustc_data_structures::fx::FxHashSet; use rustc_hir::{EnumDef, FieldDef, Item, ItemKind, OwnerId, Variant, VariantData}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; @@ -147,6 +148,7 @@ pub struct ItemNameRepetitions { struct_threshold: u64, avoid_breaking_exported_api: bool, allow_private_module_inception: bool, + allowed_prefixes: FxHashSet, } impl ItemNameRepetitions { @@ -156,6 +158,7 @@ impl ItemNameRepetitions { struct_threshold: u64, avoid_breaking_exported_api: bool, allow_private_module_inception: bool, + allowed_prefixes: &[String], ) -> Self { Self { modules: Vec::new(), @@ -163,8 +166,13 @@ impl ItemNameRepetitions { struct_threshold, avoid_breaking_exported_api, allow_private_module_inception, + allowed_prefixes: allowed_prefixes.iter().map(|s| to_camel_case(s)).collect(), } } + + fn is_allowed_prefix(&self, prefix: &str) -> bool { + self.allowed_prefixes.contains(prefix) + } } impl_lint_pass!(ItemNameRepetitions => [ @@ -423,7 +431,9 @@ impl LateLintPass<'_> for ItemNameRepetitions { _ => (), } } - if rmatching.char_count == nchars { + if rmatching.char_count == nchars + && !self.is_allowed_prefix(&item_camel[..item_camel.len() - rmatching.byte_count]) + { span_lint( cx, MODULE_NAME_REPETITIONS, diff --git a/clippy_lints/src/legacy_numeric_constants.rs b/clippy_lints/src/legacy_numeric_constants.rs index c5f1afe68c3f..00124dcdd91d 100644 --- a/clippy_lints/src/legacy_numeric_constants.rs +++ b/clippy_lints/src/legacy_numeric_constants.rs @@ -17,7 +17,7 @@ declare_clippy_lint! { /// `std::::EPSILON`, etc. /// /// ### Why is this bad? - /// All of these have been superceded by the associated constants on their respective types, + /// All of these have been superseded by the associated constants on their respective types, /// such as `i128::MAX`. These legacy items may be deprecated in a future version of rust. /// /// ### Example diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index b92364a9d147..e2aac58bf979 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -594,6 +594,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { pub_underscore_fields_behavior, ref allowed_duplicate_crates, allow_comparison_to_zero, + ref allowed_prefixes, blacklisted_names: _, cyclomatic_complexity_threshold: _, @@ -864,6 +865,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { struct_field_name_threshold, avoid_breaking_exported_api, allow_private_module_inception, + allowed_prefixes, )) }); store.register_early_pass(|| Box::new(tabs_in_doc_comments::TabsInDocComments)); diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 2bb63ec2b046..443d6189c1f7 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -291,10 +291,7 @@ fn elision_suggestions( }) => { // expand `&'a T` to `&'a T` // ^^ ^^^ - let span = cx - .sess() - .source_map() - .span_extend_while_whitespace(usage.ident.span); + let span = cx.sess().source_map().span_extend_while_whitespace(usage.ident.span); (span, String::new()) }, diff --git a/clippy_lints/src/manual_unwrap_or_default.rs b/clippy_lints/src/manual_unwrap_or_default.rs index c562ceb5bcee..84fb183e3f79 100644 --- a/clippy_lints/src/manual_unwrap_or_default.rs +++ b/clippy_lints/src/manual_unwrap_or_default.rs @@ -1,13 +1,14 @@ -use clippy_utils::sugg::Sugg; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::{Arm, Expr, ExprKind, HirId, LangItem, MatchSource, Pat, PatKind, QPath}; use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::ty::GenericArgKind; use rustc_session::declare_lint_pass; use rustc_span::sym; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::snippet_opt; +use clippy_utils::higher::IfLetOrMatch; +use clippy_utils::sugg::Sugg; use clippy_utils::ty::implements_trait; use clippy_utils::{in_constant, is_default_equivalent, peel_blocks, span_contains_comment}; @@ -105,19 +106,39 @@ fn get_some_and_none_bodies<'tcx>( } } -fn handle_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool { - let ExprKind::Match(match_expr, [arm1, arm2], MatchSource::Normal | MatchSource::ForLoopDesugar) = expr.kind else { - return false; +#[allow(clippy::needless_pass_by_value)] +fn handle<'tcx>(cx: &LateContext<'tcx>, if_let_or_match: IfLetOrMatch<'tcx>, expr: &'tcx Expr<'tcx>) { + // Get expr_name ("if let" or "match" depending on kind of expression), the condition, the body for + // the some arm, the body for the none arm and the binding id of the some arm + let (expr_name, condition, body_some, body_none, binding_id) = match if_let_or_match { + IfLetOrMatch::Match(condition, [arm1, arm2], MatchSource::Normal | MatchSource::ForLoopDesugar) + // Make sure there are no guards to keep things simple + if arm1.guard.is_none() + && arm2.guard.is_none() + // Get the some and none bodies and the binding id of the some arm + && let Some(((body_some, binding_id), body_none)) = get_some_and_none_bodies(cx, arm1, arm2) => + { + ("match", condition, body_some, body_none, binding_id) + }, + IfLetOrMatch::IfLet(condition, pat, if_expr, Some(else_expr), _) + if let Some(binding_id) = get_some(cx, pat) => + { + ("if let", condition, if_expr, else_expr, binding_id) + }, + _ => { + // All other cases (match with number of arms != 2, if let without else, etc.) + return; + }, }; - // We don't want conditions on the arms to simplify things. - if arm1.guard.is_none() - && arm2.guard.is_none() - // We check that the returned type implements the `Default` trait. - && let match_ty = cx.typeck_results().expr_ty(expr) - && let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default) - && implements_trait(cx, match_ty, default_trait_id, &[]) - // We now get the bodies for both the `Some` and `None` arms. - && let Some(((body_some, binding_id), body_none)) = get_some_and_none_bodies(cx, arm1, arm2) + + // We check if the return type of the expression implements Default. + let expr_type = cx.typeck_results().expr_ty(expr); + if let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default) + && implements_trait(cx, expr_type, default_trait_id, &[]) + // We check if the initial condition implements Default. + && let Some(condition_ty) = cx.typeck_results().expr_ty(condition).walk().nth(1) + && let GenericArgKind::Type(condition_ty) = condition_ty.unpack() + && implements_trait(cx, condition_ty, default_trait_id, &[]) // We check that the `Some(x) => x` doesn't do anything apart "returning" the value in `Some`. && let ExprKind::Path(QPath::Resolved(_, path)) = peel_blocks(body_some).kind && let Res::Local(local_id) = path.res @@ -125,8 +146,9 @@ fn handle_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool { // We now check the `None` arm is calling a method equivalent to `Default::default`. && let body_none = peel_blocks(body_none) && is_default_equivalent(cx, body_none) - && let Some(receiver) = Sugg::hir_opt(cx, match_expr).map(Sugg::maybe_par) + && let Some(receiver) = Sugg::hir_opt(cx, condition).map(Sugg::maybe_par) { + // Machine applicable only if there are no comments present let applicability = if span_contains_comment(cx.sess().source_map(), expr.span) { Applicability::MaybeIncorrect } else { @@ -136,48 +158,12 @@ fn handle_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool { cx, MANUAL_UNWRAP_OR_DEFAULT, expr.span, - "match can be simplified with `.unwrap_or_default()`", + format!("{expr_name} can be simplified with `.unwrap_or_default()`"), "replace it with", format!("{receiver}.unwrap_or_default()"), applicability, ); } - true -} - -fn handle_if_let<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { - if let ExprKind::If(cond, if_block, Some(else_expr)) = expr.kind - && let ExprKind::Let(let_) = cond.kind - && let ExprKind::Block(_, _) = else_expr.kind - // We check that the returned type implements the `Default` trait. - && let match_ty = cx.typeck_results().expr_ty(expr) - && let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default) - && implements_trait(cx, match_ty, default_trait_id, &[]) - && let Some(binding_id) = get_some(cx, let_.pat) - // We check that the `Some(x) => x` doesn't do anything apart "returning" the value in `Some`. - && let ExprKind::Path(QPath::Resolved(_, path)) = peel_blocks(if_block).kind - && let Res::Local(local_id) = path.res - && local_id == binding_id - // We now check the `None` arm is calling a method equivalent to `Default::default`. - && let body_else = peel_blocks(else_expr) - && is_default_equivalent(cx, body_else) - && let Some(if_let_expr_snippet) = snippet_opt(cx, let_.init.span) - { - let applicability = if span_contains_comment(cx.sess().source_map(), expr.span) { - Applicability::MaybeIncorrect - } else { - Applicability::MachineApplicable - }; - span_lint_and_sugg( - cx, - MANUAL_UNWRAP_OR_DEFAULT, - expr.span, - "if let can be simplified with `.unwrap_or_default()`", - "replace it with", - format!("{if_let_expr_snippet}.unwrap_or_default()"), - applicability, - ); - } } impl<'tcx> LateLintPass<'tcx> for ManualUnwrapOrDefault { @@ -185,8 +171,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualUnwrapOrDefault { if expr.span.from_expansion() || in_constant(cx, expr.hir_id) { return; } - if !handle_match(cx, expr) { - handle_if_let(cx, expr); + // Call handle only if the expression is `if let` or `match` + if let Some(if_let_or_match) = IfLetOrMatch::parse(cx, expr) { + handle(cx, if_let_or_match, expr); } } } diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 2fb317c8c68e..0939c0285642 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -3938,7 +3938,6 @@ declare_clippy_lint! { /// This lint cannot detect if the split is intentionally restricted to a single type of newline (`"\n"` or /// `"\r\n"`), for example during the parsing of a specific file format in which precisely one newline type is /// valid. - /// ``` #[clippy::version = "1.77.0"] pub STR_SPLIT_AT_NEWLINE, pedantic, diff --git a/clippy_lints/src/methods/search_is_some.rs b/clippy_lints/src/methods/search_is_some.rs index ac5cc2f01e53..f5f1e94bbf45 100644 --- a/clippy_lints/src/methods/search_is_some.rs +++ b/clippy_lints/src/methods/search_is_some.rs @@ -2,7 +2,8 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::sugg::deref_closure_args; use clippy_utils::ty::is_type_lang_item; -use clippy_utils::{is_trait_method, strip_pat_refs}; +use clippy_utils::{get_parent_expr, is_trait_method, strip_pat_refs}; +use hir::ExprKind; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::PatKind; @@ -35,7 +36,7 @@ pub(super) fn check<'tcx>( // suggest `any(|..| *..)` instead of `any(|..| **..)` for `find(|..| **..).is_some()` let mut applicability = Applicability::MachineApplicable; let any_search_snippet = if search_method == "find" - && let hir::ExprKind::Closure(&hir::Closure { body, .. }) = search_arg.kind + && let ExprKind::Closure(&hir::Closure { body, .. }) = search_arg.kind && let closure_body = cx.tcx.hir().body(body) && let Some(closure_arg) = closure_body.params.first() { @@ -72,16 +73,24 @@ pub(super) fn check<'tcx>( ); } else { let iter = snippet(cx, search_recv.span, ".."); + let sugg = if is_receiver_of_method_call(cx, expr) { + format!( + "(!{iter}.any({}))", + any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str) + ) + } else { + format!( + "!{iter}.any({})", + any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str) + ) + }; span_lint_and_sugg( cx, SEARCH_IS_SOME, expr.span, msg, "consider using", - format!( - "!{iter}.any({})", - any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str) - ), + sugg, applicability, ); } @@ -127,13 +136,18 @@ pub(super) fn check<'tcx>( let string = snippet(cx, search_recv.span, ".."); let mut applicability = Applicability::MachineApplicable; let find_arg = snippet_with_applicability(cx, search_arg.span, "..", &mut applicability); + let sugg = if is_receiver_of_method_call(cx, expr) { + format!("(!{string}.contains({find_arg}))") + } else { + format!("!{string}.contains({find_arg})") + }; span_lint_and_sugg( cx, SEARCH_IS_SOME, expr.span, msg, "consider using", - format!("!{string}.contains({find_arg})"), + sugg, applicability, ); }, @@ -142,3 +156,13 @@ pub(super) fn check<'tcx>( } } } + +fn is_receiver_of_method_call(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { + if let Some(parent_expr) = get_parent_expr(cx, expr) + && let ExprKind::MethodCall(_, receiver, ..) = parent_expr.kind + && receiver.hir_id == expr.hir_id + { + return true; + } + false +} diff --git a/clippy_lints/src/needless_borrows_for_generic_args.rs b/clippy_lints/src/needless_borrows_for_generic_args.rs index c555fc8675c8..a24cd4f9c8a3 100644 --- a/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -23,7 +23,7 @@ use std::collections::VecDeque; declare_clippy_lint! { /// ### What it does - /// Checks for borrow operations (`&`) that used as a generic argument to a + /// Checks for borrow operations (`&`) that are used as a generic argument to a /// function when the borrowed value could be used. /// /// ### Why is this bad? diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index 5ca388d67a17..ff10a841aef1 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -18,7 +18,7 @@ use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult, GlobalId}; use rustc_middle::ty::adjustment::Adjust; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::impl_lint_pass; -use rustc_span::{sym, DUMMY_SP, InnerSpan, Span}; +use rustc_span::{sym, InnerSpan, Span, DUMMY_SP}; use rustc_target::abi::VariantIdx; // FIXME: this is a correctness problem but there's no suitable @@ -297,12 +297,7 @@ impl NonCopyConst { fn is_value_unfrozen_expr<'tcx>(&self, cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool { let args = cx.typeck_results().node_args(hir_id); - let result = Self::const_eval_resolve( - cx.tcx, - cx.param_env, - ty::UnevaluatedConst::new(def_id, args), - DUMMY_SP, - ); + let result = Self::const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, args), DUMMY_SP); self.is_value_unfrozen_raw(cx, result, ty) } diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index 3aa979cb11b9..87a3c3874d77 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -300,11 +300,8 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { e.span, "calling `as_bytes()` on `include_str!(..)`", "consider using `include_bytes!(..)` instead", - snippet_with_applicability(cx, receiver.span.source_callsite(), r#""foo""#, &mut applicability).replacen( - "include_str", - "include_bytes", - 1, - ), + snippet_with_applicability(cx, receiver.span.source_callsite(), r#""foo""#, &mut applicability) + .replacen("include_str", "include_bytes", 1), applicability, ); } else if lit_content.as_str().is_ascii() diff --git a/clippy_lints/src/transmute/transmute_int_to_non_zero.rs b/clippy_lints/src/transmute/transmute_int_to_non_zero.rs index 234021f0f479..2bea3be3d603 100644 --- a/clippy_lints/src/transmute/transmute_int_to_non_zero.rs +++ b/clippy_lints/src/transmute/transmute_int_to_non_zero.rs @@ -27,7 +27,7 @@ pub(super) fn check<'tcx>( }; // FIXME: This can be simplified once `NonZero` is stable. - let coercable_types = [ + let coercible_types = [ ("NonZeroU8", tcx.types.u8), ("NonZeroU16", tcx.types.u16), ("NonZeroU32", tcx.types.u32), @@ -44,7 +44,7 @@ pub(super) fn check<'tcx>( let int_type = substs.type_at(0); - let Some(nonzero_alias) = coercable_types.iter().find_map(|(nonzero_alias, t)| { + let Some(nonzero_alias) = coercible_types.iter().find_map(|(nonzero_alias, t)| { if *t == int_type && *t == from_ty { Some(nonzero_alias) } else { diff --git a/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs b/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs index a6a6e9a3bac3..ba8c7d6bfcb4 100644 --- a/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs +++ b/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs @@ -1,10 +1,10 @@ -use rustc_hir_typeck::cast::check_cast; use super::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::sugg::Sugg; use rustc_ast::ExprPrecedence; use rustc_errors::Applicability; use rustc_hir::{Expr, Node}; +use rustc_hir_typeck::cast::check_cast; use rustc_lint::LateContext; use rustc_middle::ty::cast::CastKind; use rustc_middle::ty::Ty; diff --git a/clippy_utils/src/ast_utils.rs b/clippy_utils/src/ast_utils.rs index 9f0bd4ea7e2e..0395eb1449b4 100644 --- a/clippy_utils/src/ast_utils.rs +++ b/clippy_utils/src/ast_utils.rs @@ -709,8 +709,12 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool { (Tup(l), Tup(r)) => over(l, r, |l, r| eq_ty(l, r)), (Path(lq, lp), Path(rq, rp)) => both(lq, rq, eq_qself) && eq_path(lp, rp), (TraitObject(lg, ls), TraitObject(rg, rs)) => ls == rs && over(lg, rg, eq_generic_bound), - (ImplTrait(_, lg, lc), ImplTrait(_, rg, rc)) => - over(lg, rg, eq_generic_bound) && both(lc, rc, |lc, rc| over(lc.0.as_slice(), rc.0.as_slice(), eq_precise_capture)), + (ImplTrait(_, lg, lc), ImplTrait(_, rg, rc)) => { + over(lg, rg, eq_generic_bound) + && both(lc, rc, |lc, rc| { + over(lc.0.as_slice(), rc.0.as_slice(), eq_precise_capture) + }) + }, (Typeof(l), Typeof(r)) => eq_expr(&l.value, &r.value), (MacCall(l), MacCall(r)) => eq_mac_call(l, r), _ => false, diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index aac699eed239..5e242aea354a 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -3285,7 +3285,7 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St Right(r) => Right(r.data), }); - // 2. for the remaning segments, construct relative path using only mod names and `super` + // 2. for the remaining segments, construct relative path using only mod names and `super` let mut go_up_by = 0; let mut path = Vec::new(); for el in unique_parts { diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index 1afc5ed0157a..a06a82c56530 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -10,7 +10,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{Expr, FnDecl, LangItem, TyKind, Unsafety}; -use rustc_infer::infer::type_variable::{TypeVariableOrigin}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::mir::interpret::Scalar; diff --git a/clippy_utils/src/ty/type_certainty/mod.rs b/clippy_utils/src/ty/type_certainty/mod.rs index 762830ffd78d..2241494b484a 100644 --- a/clippy_utils/src/ty/type_certainty/mod.rs +++ b/clippy_utils/src/ty/type_certainty/mod.rs @@ -90,7 +90,7 @@ fn expr_type_certainty(cx: &LateContext<'_>, expr: &Expr<'_>) -> Certainty { if let Some(def_id) = adt_def_id(expr_ty) { certainty.with_def_id(def_id) } else { - certainty + certainty.clear_def_id() } } diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs index 4251151c4543..deb06094d83b 100644 --- a/lintcheck/src/main.rs +++ b/lintcheck/src/main.rs @@ -26,12 +26,12 @@ use std::env::consts::EXE_SUFFIX; use std::fmt::{self, Write as _}; use std::io::{self, ErrorKind}; use std::path::{Path, PathBuf}; -use std::process::Command; +use std::process::{Command, ExitStatus}; use std::sync::atomic::{AtomicUsize, Ordering}; use std::time::Duration; use std::{env, fs, thread}; -use cargo_metadata::diagnostic::{Diagnostic, DiagnosticLevel}; +use cargo_metadata::diagnostic::Diagnostic; use cargo_metadata::Message; use rayon::prelude::*; use serde::{Deserialize, Serialize}; @@ -97,16 +97,43 @@ struct Crate { options: Option>, } +/// A single emitted output from clippy being executed on a crate. It may either be a +/// `ClippyWarning`, or a `RustcIce` caused by a panic within clippy. A crate may have many +/// `ClippyWarning`s but a maximum of one `RustcIce` (at which point clippy halts execution). +#[derive(Debug)] +enum ClippyCheckOutput { + ClippyWarning(ClippyWarning), + RustcIce(RustcIce), +} + +#[derive(Debug)] +struct RustcIce { + pub crate_name: String, + pub ice_content: String, +} +impl RustcIce { + pub fn from_stderr_and_status(crate_name: &str, status: ExitStatus, stderr: &str) -> Option { + if status.code().unwrap_or(0) == 101 + /* ice exit status */ + { + Some(Self { + crate_name: crate_name.to_owned(), + ice_content: stderr.to_owned(), + }) + } else { + None + } + } +} + /// A single warning that clippy issued while checking a `Crate` #[derive(Debug)] struct ClippyWarning { - crate_name: String, file: String, line: usize, column: usize, lint_type: String, message: String, - is_ice: bool, } #[allow(unused)] @@ -131,13 +158,11 @@ impl ClippyWarning { }; Some(Self { - crate_name: crate_name.to_owned(), file, line: span.line_start, column: span.column_start, lint_type, message: diag.message, - is_ice: diag.level == DiagnosticLevel::Ice, }) } @@ -318,7 +343,7 @@ impl Crate { config: &LintcheckConfig, lint_filter: &[String], server: &Option, - ) -> Vec { + ) -> Vec { // advance the atomic index by one let index = target_dir_index.fetch_add(1, Ordering::SeqCst); // "loop" the index within 0..thread_limit @@ -342,9 +367,9 @@ impl Crate { let shared_target_dir = clippy_project_root().join("target/lintcheck/shared_target_dir"); let mut cargo_clippy_args = if config.fix { - vec!["--fix", "--"] + vec!["--quiet", "--fix", "--"] } else { - vec!["--", "--message-format=json", "--"] + vec!["--quiet", "--message-format=json", "--"] }; let mut clippy_args = Vec::<&str>::new(); @@ -435,14 +460,21 @@ impl Crate { } // get all clippy warnings and ICEs - let warnings: Vec = Message::parse_stream(stdout.as_bytes()) + let mut entries: Vec = Message::parse_stream(stdout.as_bytes()) .filter_map(|msg| match msg { Ok(Message::CompilerMessage(message)) => ClippyWarning::new(message.message, &self.name, &self.version), _ => None, }) + .map(ClippyCheckOutput::ClippyWarning) .collect(); - warnings + if let Some(ice) = RustcIce::from_stderr_and_status(&self.name, *status, &stderr) { + entries.push(ClippyCheckOutput::RustcIce(ice)); + } else if !status.success() { + println!("non-ICE bad exit status for {} {}: {}", self.name, self.version, stderr); + } + + entries } } @@ -642,7 +674,7 @@ fn main() { LintcheckServer::spawn(recursive_options) }); - let mut clippy_warnings: Vec = crates + let mut clippy_entries: Vec = crates .par_iter() .flat_map(|krate| { krate.run_clippy_lints( @@ -658,7 +690,9 @@ fn main() { .collect(); if let Some(server) = server { - clippy_warnings.extend(server.warnings()); + let server_clippy_entries = server.warnings().map(ClippyCheckOutput::ClippyWarning); + + clippy_entries.extend(server_clippy_entries); } // if we are in --fix mode, don't change the log files, terminate here @@ -666,20 +700,21 @@ fn main() { return; } + // split up warnings and ices + let mut warnings: Vec = vec![]; + let mut raw_ices: Vec = vec![]; + for entry in clippy_entries { + if let ClippyCheckOutput::ClippyWarning(x) = entry { + warnings.push(x); + } else if let ClippyCheckOutput::RustcIce(x) = entry { + raw_ices.push(x); + } + } + // generate some stats - let (stats_formatted, new_stats) = gather_stats(&clippy_warnings); + let (stats_formatted, new_stats) = gather_stats(&warnings); - // grab crashes/ICEs, save the crate name and the ice message - let ices: Vec<(&String, &String)> = clippy_warnings - .iter() - .filter(|warning| warning.is_ice) - .map(|w| (&w.crate_name, &w.message)) - .collect(); - - let mut all_msgs: Vec = clippy_warnings - .iter() - .map(|warn| warn.to_output(config.markdown)) - .collect(); + let mut all_msgs: Vec = warnings.iter().map(|warn| warn.to_output(config.markdown)).collect(); all_msgs.sort(); all_msgs.push("\n\n### Stats:\n\n".into()); all_msgs.push(stats_formatted); @@ -693,11 +728,18 @@ fn main() { } write!(text, "{}", all_msgs.join("")).unwrap(); text.push_str("\n\n### ICEs:\n"); - for (cratename, msg) in &ices { - let _: fmt::Result = write!(text, "{cratename}: '{msg}'"); + for ice in &raw_ices { + let _: fmt::Result = write!( + text, + "{}:\n{}\n========================================\n\n", + ice.crate_name, ice.ice_content + ); } println!("Writing logs to {}", config.lintcheck_results_path.display()); + if !raw_ices.is_empty() { + println!("WARNING: at least one ICE reported, check log file"); + } fs::create_dir_all(config.lintcheck_results_path.parent().unwrap()).unwrap(); fs::write(&config.lintcheck_results_path, text).unwrap(); diff --git a/rust-toolchain b/rust-toolchain index b2fe5c8bee7a..521c0d12983d 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-04-04" +channel = "nightly-2024-04-18" components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] diff --git a/tests/ui-internal/custom_ice_message.rs b/tests/ui-internal/custom_ice_message.rs index 400bfd5d9751..9b0db660c997 100644 --- a/tests/ui-internal/custom_ice_message.rs +++ b/tests/ui-internal/custom_ice_message.rs @@ -5,7 +5,6 @@ //@normalize-stderr-test: "'rustc'" -> "''" //@normalize-stderr-test: "rustc 1\.\d+.* running on .*" -> "rustc running on " //@normalize-stderr-test: "(?ms)query stack during panic:\n.*end of query stack\n" -> "" -//@normalize-stderr-test: "this compiler `.*` is outdated" -> "this compiler is outdated" #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute)] diff --git a/tests/ui-internal/custom_ice_message.stderr b/tests/ui-internal/custom_ice_message.stderr index 763ce59ba1d9..b99e8c0e76f0 100644 --- a/tests/ui-internal/custom_ice_message.stderr +++ b/tests/ui-internal/custom_ice_message.stderr @@ -4,10 +4,9 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: the compiler unexpectedly panicked. this is a bug. -note: it seems that this compiler is outdated, a newer nightly should have been released in the meantime - | - = note: please consider running `rustup update nightly` to update the nightly channel and check if this problem still persists - = note: if the problem still persists, we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new?template=ice.yml +note: we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new?template=ice.yml + +note: please make sure that you have updated to the latest nightly note: rustc running on diff --git a/tests/ui-toml/item_name_repetitions/allowed_prefixes/clippy.toml b/tests/ui-toml/item_name_repetitions/allowed_prefixes/clippy.toml new file mode 100644 index 000000000000..35145551b600 --- /dev/null +++ b/tests/ui-toml/item_name_repetitions/allowed_prefixes/clippy.toml @@ -0,0 +1 @@ +allowed-prefixes = ["bar"] diff --git a/tests/ui-toml/item_name_repetitions/allowed_prefixes/item_name_repetitions.rs b/tests/ui-toml/item_name_repetitions/allowed_prefixes/item_name_repetitions.rs new file mode 100644 index 000000000000..4142ced5f6b5 --- /dev/null +++ b/tests/ui-toml/item_name_repetitions/allowed_prefixes/item_name_repetitions.rs @@ -0,0 +1,15 @@ +#![warn(clippy::module_name_repetitions)] +#![allow(dead_code)] + +mod foo { + // #12544 - shouldn't warn if item name consists only of an allowed prefix and a module name. + // In this test, allowed prefixes are configured to be ["bar"]. + + // this line should produce a warning: + pub fn to_foo() {} + + // but this line shouldn't + pub fn bar_foo() {} +} + +fn main() {} diff --git a/tests/ui-toml/item_name_repetitions/allowed_prefixes/item_name_repetitions.stderr b/tests/ui-toml/item_name_repetitions/allowed_prefixes/item_name_repetitions.stderr new file mode 100644 index 000000000000..6cfe0eab4792 --- /dev/null +++ b/tests/ui-toml/item_name_repetitions/allowed_prefixes/item_name_repetitions.stderr @@ -0,0 +1,11 @@ +error: item name ends with its containing module's name + --> tests/ui-toml/item_name_repetitions/allowed_prefixes/item_name_repetitions.rs:9:12 + | +LL | pub fn to_foo() {} + | ^^^^^^ + | + = note: `-D clippy::module-name-repetitions` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::module_name_repetitions)]` + +error: aborting due to 1 previous error + diff --git a/tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/clippy.toml b/tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/clippy.toml new file mode 100644 index 000000000000..31ef524671d1 --- /dev/null +++ b/tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/clippy.toml @@ -0,0 +1 @@ +allowed-prefixes = ["..", "bar"] diff --git a/tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/item_name_repetitions.rs b/tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/item_name_repetitions.rs new file mode 100644 index 000000000000..b132305d01cf --- /dev/null +++ b/tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/item_name_repetitions.rs @@ -0,0 +1,21 @@ +#![warn(clippy::module_name_repetitions)] +#![allow(dead_code)] + +mod foo { + // #12544 - shouldn't warn if item name consists only of an allowed prefix and a module name. + // In this test, allowed prefixes are configured to be all of the default prefixes and ["bar"]. + + // this line should produce a warning: + pub fn something_foo() {} + + // but none of the following should: + pub fn bar_foo() {} + pub fn to_foo() {} + pub fn as_foo() {} + pub fn into_foo() {} + pub fn from_foo() {} + pub fn try_into_foo() {} + pub fn try_from_foo() {} +} + +fn main() {} diff --git a/tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/item_name_repetitions.stderr b/tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/item_name_repetitions.stderr new file mode 100644 index 000000000000..f495ec421841 --- /dev/null +++ b/tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/item_name_repetitions.stderr @@ -0,0 +1,11 @@ +error: item name ends with its containing module's name + --> tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/item_name_repetitions.rs:9:12 + | +LL | pub fn something_foo() {} + | ^^^^^^^^^^^^^ + | + = note: `-D clippy::module-name-repetitions` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::module_name_repetitions)]` + +error: aborting due to 1 previous error + diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 737c062ea562..24645b61fdb0 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -14,6 +14,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect allowed-dotfiles allowed-duplicate-crates allowed-idents-below-min-chars + allowed-prefixes allowed-scripts allowed-wildcard-imports arithmetic-side-effects-allowed @@ -93,6 +94,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect allowed-dotfiles allowed-duplicate-crates allowed-idents-below-min-chars + allowed-prefixes allowed-scripts allowed-wildcard-imports arithmetic-side-effects-allowed @@ -172,6 +174,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni allowed-dotfiles allowed-duplicate-crates allowed-idents-below-min-chars + allowed-prefixes allowed-scripts allowed-wildcard-imports arithmetic-side-effects-allowed diff --git a/tests/ui/arc_with_non_send_sync.rs b/tests/ui/arc_with_non_send_sync.rs index 349e81912e3c..c287480bb1fd 100644 --- a/tests/ui/arc_with_non_send_sync.rs +++ b/tests/ui/arc_with_non_send_sync.rs @@ -33,16 +33,9 @@ fn main() { let _ = Arc::new(42); let _ = Arc::new(RefCell::new(42)); - //~^ ERROR: usage of an `Arc` that is not `Send` and `Sync` - //~| NOTE: the trait `Sync` is not implemented for `RefCell` let mutex = Mutex::new(1); let _ = Arc::new(mutex.lock().unwrap()); - //~^ ERROR: usage of an `Arc` that is not `Send` and `Sync` - //~| NOTE: the trait `Send` is not implemented for `MutexGuard<'_, i32>` let _ = Arc::new(&42 as *const i32); - //~^ ERROR: usage of an `Arc` that is not `Send` and `Sync` - //~| NOTE: the trait `Send` is not implemented for `*const i32` - //~| NOTE: the trait `Sync` is not implemented for `*const i32` } diff --git a/tests/ui/arc_with_non_send_sync.stderr b/tests/ui/arc_with_non_send_sync.stderr index d4e630376204..da363a3ebdd9 100644 --- a/tests/ui/arc_with_non_send_sync.stderr +++ b/tests/ui/arc_with_non_send_sync.stderr @@ -4,38 +4,31 @@ error: usage of an `Arc` that is not `Send` and `Sync` LL | let _ = Arc::new(RefCell::new(42)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `Arc>` is not `Send` and `Sync` as: - = note: - the trait `Sync` is not implemented for `RefCell` - = help: consider using an `Rc` instead. `Arc` does not provide benefits for non `Send` and `Sync` types - = note: if you intend to use `Arc` with `Send` and `Sync` traits - = note: wrap the inner type with a `Mutex` or implement `Send` and `Sync` for `RefCell` + = note: `Arc>` is not `Send` and `Sync` as `RefCell` is not `Sync` + = help: if the `Arc` will not used be across threads replace it with an `Rc` + = help: otherwise make `RefCell` `Send` and `Sync` or consider a wrapper type such as `Mutex` = note: `-D clippy::arc-with-non-send-sync` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::arc_with_non_send_sync)]` error: usage of an `Arc` that is not `Send` and `Sync` - --> tests/ui/arc_with_non_send_sync.rs:40:13 + --> tests/ui/arc_with_non_send_sync.rs:38:13 | LL | let _ = Arc::new(mutex.lock().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `Arc>` is not `Send` and `Sync` as: - = note: - the trait `Send` is not implemented for `MutexGuard<'_, i32>` - = help: consider using an `Rc` instead. `Arc` does not provide benefits for non `Send` and `Sync` types - = note: if you intend to use `Arc` with `Send` and `Sync` traits - = note: wrap the inner type with a `Mutex` or implement `Send` and `Sync` for `MutexGuard<'_, i32>` + = note: `Arc>` is not `Send` and `Sync` as `MutexGuard<'_, i32>` is not `Send` + = help: if the `Arc` will not used be across threads replace it with an `Rc` + = help: otherwise make `MutexGuard<'_, i32>` `Send` and `Sync` or consider a wrapper type such as `Mutex` error: usage of an `Arc` that is not `Send` and `Sync` - --> tests/ui/arc_with_non_send_sync.rs:44:13 + --> tests/ui/arc_with_non_send_sync.rs:40:13 | LL | let _ = Arc::new(&42 as *const i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `Arc<*const i32>` is not `Send` and `Sync` as: - = note: - the trait `Send` is not implemented for `*const i32` - = note: - the trait `Sync` is not implemented for `*const i32` - = help: consider using an `Rc` instead. `Arc` does not provide benefits for non `Send` and `Sync` types - = note: if you intend to use `Arc` with `Send` and `Sync` traits - = note: wrap the inner type with a `Mutex` or implement `Send` and `Sync` for `*const i32` + = note: `Arc<*const i32>` is not `Send` and `Sync` as `*const i32` is neither `Send` nor `Sync` + = help: if the `Arc` will not used be across threads replace it with an `Rc` + = help: otherwise make `*const i32` `Send` and `Sync` or consider a wrapper type such as `Mutex` error: aborting due to 3 previous errors diff --git a/tests/ui/auxiliary/proc_macro_attr.rs b/tests/ui/auxiliary/proc_macro_attr.rs index a6f3b164c9ba..f6fdebaf2527 100644 --- a/tests/ui/auxiliary/proc_macro_attr.rs +++ b/tests/ui/auxiliary/proc_macro_attr.rs @@ -176,3 +176,17 @@ pub fn with_empty_docs(_attr: TokenStream, input: TokenStream) -> TokenStream { } .into() } + +#[proc_macro_attribute] +pub fn duplicated_attr(_attr: TokenStream, input: TokenStream) -> TokenStream { + let item = parse_macro_input!(input as syn::Item); + let attrs: Vec = vec![]; + quote! { + #(#attrs)* + #[allow(unused)] + #[allow(unused)] + #[allow(unused)] + #item + } + .into() +} diff --git a/tests/ui/cast.rs b/tests/ui/cast.rs index ce76ad3d3ad1..215c008902d2 100644 --- a/tests/ui/cast.rs +++ b/tests/ui/cast.rs @@ -463,6 +463,18 @@ fn issue11642() { } } +fn issue11738() { + macro_rules! m { + () => { + let _ = i32::MIN as u32; // cast_sign_loss + let _ = u32::MAX as u8; // cast_possible_truncation + let _ = std::f64::consts::PI as f32; // cast_possible_truncation + let _ = 0i8 as i32; // cast_lossless + }; + } + m!(); +} + fn issue12506() -> usize { let bar: Result, u32> = Ok(Some(10)); bar.unwrap().unwrap() as usize diff --git a/tests/ui/cast.stderr b/tests/ui/cast.stderr index 3736e8aee0af..8b269c471765 100644 --- a/tests/ui/cast.stderr +++ b/tests/ui/cast.stderr @@ -650,8 +650,47 @@ error: casting `i32` to `u32` may lose the sign of the value LL | (a.abs() * b.pow(2) / c.abs()) as u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: casting `i32` to `u32` may lose the sign of the value + --> tests/ui/cast.rs:469:21 + | +LL | let _ = i32::MIN as u32; // cast_sign_loss + | ^^^^^^^^^^^^^^^ +... +LL | m!(); + | ---- in this macro invocation + | + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: casting `u32` to `u8` may truncate the value + --> tests/ui/cast.rs:470:21 + | +LL | let _ = u32::MAX as u8; // cast_possible_truncation + | ^^^^^^^^^^^^^^ +... +LL | m!(); + | ---- in this macro invocation + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) +help: ... or use `try_from` and handle the error accordingly + | +LL | let _ = u8::try_from(u32::MAX); // cast_possible_truncation + | ~~~~~~~~~~~~~~~~~~~~~~ + +error: casting `f64` to `f32` may truncate the value + --> tests/ui/cast.rs:471:21 + | +LL | let _ = std::f64::consts::PI as f32; // cast_possible_truncation + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | m!(); + | ---- in this macro invocation + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:468:5 + --> tests/ui/cast.rs:480:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -663,10 +702,10 @@ LL | usize::try_from(bar.unwrap().unwrap()) | error: casting `i64` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:468:5 + --> tests/ui/cast.rs:480:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 87 previous errors +error: aborting due to 90 previous errors diff --git a/tests/ui/crashes/ice-12585.rs b/tests/ui/crashes/ice-12585.rs new file mode 100644 index 000000000000..7928115c0a94 --- /dev/null +++ b/tests/ui/crashes/ice-12585.rs @@ -0,0 +1,26 @@ +#![allow(clippy::unit_arg)] + +struct One { + x: i32, +} +struct Two { + x: i32, +} + +struct Product {} + +impl Product { + pub fn a_method(self, _: ()) {} +} + +fn from_array(_: [i32; 2]) -> Product { + todo!() +} + +pub fn main() { + let one = One { x: 1 }; + let two = Two { x: 2 }; + + let product = from_array([one.x, two.x]); + product.a_method(<()>::default()); +} diff --git a/tests/ui/crashes/ice-12616.stderr b/tests/ui/crashes/ice-12616.stderr index ef573f55cf36..c7cf5cf5483f 100644 --- a/tests/ui/crashes/ice-12616.stderr +++ b/tests/ui/crashes/ice-12616.stderr @@ -7,13 +7,5 @@ LL | s() as *const (); = note: `-D clippy::ptr-as-ptr` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::ptr_as_ptr)]` -error: `as` casting between raw pointers without changing its mutability - --> tests/ui/crashes/ice-12616.rs:6:5 - | -LL | s() as *const (); - | ^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `s().cast::<()>()` - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/doc/doc-fixable.fixed b/tests/ui/doc/doc-fixable.fixed index 178d4a1aa2bb..7e22c847b1bc 100644 --- a/tests/ui/doc/doc-fixable.fixed +++ b/tests/ui/doc/doc-fixable.fixed @@ -235,3 +235,8 @@ fn parenthesized_word() {} /// OSes /// UXes fn plural_acronym_test() {} + +extern { + /// `foo()` + fn in_extern(); +} diff --git a/tests/ui/doc/doc-fixable.rs b/tests/ui/doc/doc-fixable.rs index 01edb44c64c1..3e2cb0df54b0 100644 --- a/tests/ui/doc/doc-fixable.rs +++ b/tests/ui/doc/doc-fixable.rs @@ -235,3 +235,8 @@ fn parenthesized_word() {} /// OSes /// UXes fn plural_acronym_test() {} + +extern { + /// foo() + fn in_extern(); +} diff --git a/tests/ui/doc/doc-fixable.stderr b/tests/ui/doc/doc-fixable.stderr index ac876306b39c..cd2228c47e35 100644 --- a/tests/ui/doc/doc-fixable.stderr +++ b/tests/ui/doc/doc-fixable.stderr @@ -352,5 +352,16 @@ help: try LL | /// `ABes` | ~~~~~~ -error: aborting due to 32 previous errors +error: item in documentation is missing backticks + --> tests/ui/doc/doc-fixable.rs:240:9 + | +LL | /// foo() + | ^^^^^ + | +help: try + | +LL | /// `foo()` + | ~~~~~~~ + +error: aborting due to 33 previous errors diff --git a/tests/ui/duplicated_attributes.rs b/tests/ui/duplicated_attributes.rs index d051c881f15b..d51e7e37beb6 100644 --- a/tests/ui/duplicated_attributes.rs +++ b/tests/ui/duplicated_attributes.rs @@ -1,9 +1,14 @@ +//@aux-build:proc_macro_attr.rs + #![warn(clippy::duplicated_attributes)] #![cfg(any(unix, windows))] #![allow(dead_code)] #![allow(dead_code)] //~ ERROR: duplicated attribute #![cfg(any(unix, windows))] // Should not warn! +#[macro_use] +extern crate proc_macro_attr; + #[cfg(any(unix, windows, target_os = "linux"))] #[allow(dead_code)] #[allow(dead_code)] //~ ERROR: duplicated attribute @@ -12,7 +17,10 @@ fn foo() {} #[cfg(unix)] #[cfg(windows)] -#[cfg(unix)] //~ ERROR: duplicated attribute +#[cfg(unix)] // cfgs are not handled fn bar() {} +#[proc_macro_attr::duplicated_attr()] // Should not warn! +fn babar() {} + fn main() {} diff --git a/tests/ui/duplicated_attributes.stderr b/tests/ui/duplicated_attributes.stderr index 9e26ba990ac1..0903617a8d1f 100644 --- a/tests/ui/duplicated_attributes.stderr +++ b/tests/ui/duplicated_attributes.stderr @@ -1,16 +1,16 @@ error: duplicated attribute - --> tests/ui/duplicated_attributes.rs:4:10 + --> tests/ui/duplicated_attributes.rs:6:10 | LL | #![allow(dead_code)] | ^^^^^^^^^ | note: first defined here - --> tests/ui/duplicated_attributes.rs:3:10 + --> tests/ui/duplicated_attributes.rs:5:10 | LL | #![allow(dead_code)] | ^^^^^^^^^ help: remove this attribute - --> tests/ui/duplicated_attributes.rs:4:10 + --> tests/ui/duplicated_attributes.rs:6:10 | LL | #![allow(dead_code)] | ^^^^^^^^^ @@ -18,38 +18,21 @@ LL | #![allow(dead_code)] = help: to override `-D warnings` add `#[allow(clippy::duplicated_attributes)]` error: duplicated attribute - --> tests/ui/duplicated_attributes.rs:9:9 + --> tests/ui/duplicated_attributes.rs:14:9 | LL | #[allow(dead_code)] | ^^^^^^^^^ | note: first defined here - --> tests/ui/duplicated_attributes.rs:8:9 + --> tests/ui/duplicated_attributes.rs:13:9 | LL | #[allow(dead_code)] | ^^^^^^^^^ help: remove this attribute - --> tests/ui/duplicated_attributes.rs:9:9 + --> tests/ui/duplicated_attributes.rs:14:9 | LL | #[allow(dead_code)] | ^^^^^^^^^ -error: duplicated attribute - --> tests/ui/duplicated_attributes.rs:15:7 - | -LL | #[cfg(unix)] - | ^^^^ - | -note: first defined here - --> tests/ui/duplicated_attributes.rs:13:7 - | -LL | #[cfg(unix)] - | ^^^^ -help: remove this attribute - --> tests/ui/duplicated_attributes.rs:15:7 - | -LL | #[cfg(unix)] - | ^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/manual_unwrap_or_default.fixed b/tests/ui/manual_unwrap_or_default.fixed index a0b707628a88..d6e736ba9cc2 100644 --- a/tests/ui/manual_unwrap_or_default.fixed +++ b/tests/ui/manual_unwrap_or_default.fixed @@ -16,6 +16,16 @@ fn main() { let x: Option> = None; x.unwrap_or_default(); + + // Issue #12564 + // No error as &Vec<_> doesn't implement std::default::Default + let mut map = std::collections::HashMap::from([(0, vec![0; 3]), (1, vec![1; 3]), (2, vec![2])]); + let x: &[_] = if let Some(x) = map.get(&0) { x } else { &[] }; + // Same code as above written using match. + let x: &[_] = match map.get(&0) { + Some(x) => x, + None => &[], + }; } // Issue #12531 diff --git a/tests/ui/manual_unwrap_or_default.rs b/tests/ui/manual_unwrap_or_default.rs index 1d4cca12f6c7..462d5d90ee77 100644 --- a/tests/ui/manual_unwrap_or_default.rs +++ b/tests/ui/manual_unwrap_or_default.rs @@ -37,6 +37,16 @@ fn main() { } else { Vec::default() }; + + // Issue #12564 + // No error as &Vec<_> doesn't implement std::default::Default + let mut map = std::collections::HashMap::from([(0, vec![0; 3]), (1, vec![1; 3]), (2, vec![2])]); + let x: &[_] = if let Some(x) = map.get(&0) { x } else { &[] }; + // Same code as above written using match. + let x: &[_] = match map.get(&0) { + Some(x) => x, + None => &[], + }; } // Issue #12531 diff --git a/tests/ui/manual_unwrap_or_default.stderr b/tests/ui/manual_unwrap_or_default.stderr index d89212e60459..3f1da444301f 100644 --- a/tests/ui/manual_unwrap_or_default.stderr +++ b/tests/ui/manual_unwrap_or_default.stderr @@ -53,7 +53,7 @@ LL | | }; | |_____^ help: replace it with: `x.unwrap_or_default()` error: match can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default.rs:46:20 + --> tests/ui/manual_unwrap_or_default.rs:56:20 | LL | Some(_) => match *b { | ____________________^ diff --git a/tests/ui/module_name_repetitions.rs b/tests/ui/module_name_repetitions.rs index a6cf03890983..b75ef87ab364 100644 --- a/tests/ui/module_name_repetitions.rs +++ b/tests/ui/module_name_repetitions.rs @@ -19,6 +19,20 @@ mod foo { // Should not warn pub struct Foobar; + + // #12544 - shouldn't warn if item name consists only of an allowed prefix and a module name. + pub fn to_foo() {} + pub fn into_foo() {} + pub fn as_foo() {} + pub fn from_foo() {} + pub fn try_into_foo() {} + pub fn try_from_foo() {} + pub trait IntoFoo {} + pub trait ToFoo {} + pub trait AsFoo {} + pub trait FromFoo {} + pub trait TryIntoFoo {} + pub trait TryFromFoo {} } fn main() {} diff --git a/tests/ui/multiple_unsafe_ops_per_block.rs b/tests/ui/multiple_unsafe_ops_per_block.rs index 8afb4df20af4..6b8a103d4a94 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.rs +++ b/tests/ui/multiple_unsafe_ops_per_block.rs @@ -1,3 +1,4 @@ +//@needs-asm-support //@aux-build:proc_macros.rs #![allow(unused)] #![allow(deref_nullptr)] diff --git a/tests/ui/multiple_unsafe_ops_per_block.stderr b/tests/ui/multiple_unsafe_ops_per_block.stderr index cff85ae115e0..e732bde0707e 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.stderr +++ b/tests/ui/multiple_unsafe_ops_per_block.stderr @@ -1,5 +1,5 @@ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:36:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:37:5 | LL | / unsafe { LL | | STATIC += 1; @@ -8,12 +8,12 @@ LL | | } | |_____^ | note: modification of a mutable static occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:37:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:38:9 | LL | STATIC += 1; | ^^^^^^^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:38:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:39:9 | LL | not_very_safe(); | ^^^^^^^^^^^^^^^ @@ -21,7 +21,7 @@ LL | not_very_safe(); = help: to override `-D warnings` add `#[allow(clippy::multiple_unsafe_ops_per_block)]` error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:45:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:46:5 | LL | / unsafe { LL | | drop(u.u); @@ -30,18 +30,18 @@ LL | | } | |_____^ | note: union field access occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:46:14 + --> tests/ui/multiple_unsafe_ops_per_block.rs:47:14 | LL | drop(u.u); | ^^^ note: raw pointer dereference occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:47:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:48:9 | LL | *raw_ptr(); | ^^^^^^^^^^ error: this `unsafe` block contains 3 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:52:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:53:5 | LL | / unsafe { LL | | asm!("nop"); @@ -51,23 +51,23 @@ LL | | } | |_____^ | note: inline assembly used here - --> tests/ui/multiple_unsafe_ops_per_block.rs:53:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:54:9 | LL | asm!("nop"); | ^^^^^^^^^^^ note: unsafe method call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:54:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:55:9 | LL | sample.not_very_safe(); | ^^^^^^^^^^^^^^^^^^^^^^ note: modification of a mutable static occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:55:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:56:9 | LL | STATIC = 0; | ^^^^^^^^^^ error: this `unsafe` block contains 6 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:61:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:62:5 | LL | / unsafe { LL | | drop(u.u); @@ -79,55 +79,55 @@ LL | | } | |_____^ | note: union field access occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:62:14 + --> tests/ui/multiple_unsafe_ops_per_block.rs:63:14 | LL | drop(u.u); | ^^^ note: access of a mutable static occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:63:14 + --> tests/ui/multiple_unsafe_ops_per_block.rs:64:14 | LL | drop(STATIC); | ^^^^^^ note: unsafe method call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:64:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:65:9 | LL | sample.not_very_safe(); | ^^^^^^^^^^^^^^^^^^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:65:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:66:9 | LL | not_very_safe(); | ^^^^^^^^^^^^^^^ note: raw pointer dereference occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:66:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:67:9 | LL | *raw_ptr(); | ^^^^^^^^^^ note: inline assembly used here - --> tests/ui/multiple_unsafe_ops_per_block.rs:67:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:68:9 | LL | asm!("nop"); | ^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:105:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:106:5 | LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:105:14 + --> tests/ui/multiple_unsafe_ops_per_block.rs:106:14 | LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: raw pointer dereference occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:105:39 + --> tests/ui/multiple_unsafe_ops_per_block.rs:106:39 | LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:123:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:124:5 | LL | / unsafe { LL | | x(); @@ -136,18 +136,18 @@ LL | | } | |_____^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:124:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:125:9 | LL | x(); | ^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:125:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:126:9 | LL | x(); | ^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:134:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:135:9 | LL | / unsafe { LL | | T::X(); @@ -156,18 +156,18 @@ LL | | } | |_________^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:135:13 + --> tests/ui/multiple_unsafe_ops_per_block.rs:136:13 | LL | T::X(); | ^^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:136:13 + --> tests/ui/multiple_unsafe_ops_per_block.rs:137:13 | LL | T::X(); | ^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> tests/ui/multiple_unsafe_ops_per_block.rs:144:5 + --> tests/ui/multiple_unsafe_ops_per_block.rs:145:5 | LL | / unsafe { LL | | x.0(); @@ -176,12 +176,12 @@ LL | | } | |_____^ | note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:145:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:146:9 | LL | x.0(); | ^^^^^ note: unsafe function call occurs here - --> tests/ui/multiple_unsafe_ops_per_block.rs:146:9 + --> tests/ui/multiple_unsafe_ops_per_block.rs:147:9 | LL | x.0(); | ^^^^^ diff --git a/tests/ui/needless_borrow.fixed b/tests/ui/needless_borrow.fixed index 998f5430fdf0..5121077b4cab 100644 --- a/tests/ui/needless_borrow.fixed +++ b/tests/ui/needless_borrow.fixed @@ -251,3 +251,11 @@ mod issue_10253 { (&S).f::<()>(); } } + +fn issue_12268() { + let option = Some((&1,)); + let x = (&1,); + option.unwrap_or((x.0,)); + //~^ ERROR: this expression creates a reference which is immediately dereferenced by the + // compiler +} diff --git a/tests/ui/needless_borrow.rs b/tests/ui/needless_borrow.rs index acb2c74d849a..e3a5cb280bad 100644 --- a/tests/ui/needless_borrow.rs +++ b/tests/ui/needless_borrow.rs @@ -251,3 +251,11 @@ mod issue_10253 { (&S).f::<()>(); } } + +fn issue_12268() { + let option = Some((&1,)); + let x = (&1,); + option.unwrap_or((&x.0,)); + //~^ ERROR: this expression creates a reference which is immediately dereferenced by the + // compiler +} diff --git a/tests/ui/needless_borrow.stderr b/tests/ui/needless_borrow.stderr index 5f0283387642..4b2b17e7e570 100644 --- a/tests/ui/needless_borrow.stderr +++ b/tests/ui/needless_borrow.stderr @@ -163,5 +163,11 @@ error: this expression borrows a value the compiler would automatically borrow LL | let _ = &mut (&mut { x.u }).x; | ^^^^^^^^^^^^^^ help: change this to: `{ x.u }` -error: aborting due to 27 previous errors +error: this expression creates a reference which is immediately dereferenced by the compiler + --> tests/ui/needless_borrow.rs:258:23 + | +LL | option.unwrap_or((&x.0,)); + | ^^^^ help: change this to: `x.0` + +error: aborting due to 28 previous errors diff --git a/tests/ui/nonminimal_bool_methods.fixed b/tests/ui/nonminimal_bool_methods.fixed index bd4be3e5a440..aba599678e39 100644 --- a/tests/ui/nonminimal_bool_methods.fixed +++ b/tests/ui/nonminimal_bool_methods.fixed @@ -109,4 +109,12 @@ fn dont_warn_for_negated_partial_ord_comparison() { let _ = !(a >= b); } +fn issue_12625() { + let a = 0; + let b = 0; + if (a as u64) < b {} //~ ERROR: this boolean expression can be simplified + if (a as u64) < b {} //~ ERROR: this boolean expression can be simplified + if a as u64 > b {} //~ ERROR: this boolean expression can be simplified +} + fn main() {} diff --git a/tests/ui/nonminimal_bool_methods.rs b/tests/ui/nonminimal_bool_methods.rs index 4523c7385df9..35f22db1d36a 100644 --- a/tests/ui/nonminimal_bool_methods.rs +++ b/tests/ui/nonminimal_bool_methods.rs @@ -109,4 +109,12 @@ fn dont_warn_for_negated_partial_ord_comparison() { let _ = !(a >= b); } +fn issue_12625() { + let a = 0; + let b = 0; + if !(a as u64 >= b) {} //~ ERROR: this boolean expression can be simplified + if !((a as u64) >= b) {} //~ ERROR: this boolean expression can be simplified + if !(a as u64 <= b) {} //~ ERROR: this boolean expression can be simplified +} + fn main() {} diff --git a/tests/ui/nonminimal_bool_methods.stderr b/tests/ui/nonminimal_bool_methods.stderr index e32c8dacd2fa..18da4e0d380b 100644 --- a/tests/ui/nonminimal_bool_methods.stderr +++ b/tests/ui/nonminimal_bool_methods.stderr @@ -79,5 +79,23 @@ error: this boolean expression can be simplified LL | if !res.is_none() {} | ^^^^^^^^^^^^^^ help: try: `res.is_some()` -error: aborting due to 13 previous errors +error: this boolean expression can be simplified + --> tests/ui/nonminimal_bool_methods.rs:115:8 + | +LL | if !(a as u64 >= b) {} + | ^^^^^^^^^^^^^^^^ help: try: `(a as u64) < b` + +error: this boolean expression can be simplified + --> tests/ui/nonminimal_bool_methods.rs:116:8 + | +LL | if !((a as u64) >= b) {} + | ^^^^^^^^^^^^^^^^^^ help: try: `(a as u64) < b` + +error: this boolean expression can be simplified + --> tests/ui/nonminimal_bool_methods.rs:117:8 + | +LL | if !(a as u64 <= b) {} + | ^^^^^^^^^^^^^^^^ help: try: `a as u64 > b` + +error: aborting due to 16 previous errors diff --git a/tests/ui/ptr_as_ptr.fixed b/tests/ui/ptr_as_ptr.fixed index 61d37b8ba3af..fa15c323540f 100644 --- a/tests/ui/ptr_as_ptr.fixed +++ b/tests/ui/ptr_as_ptr.fixed @@ -1,5 +1,4 @@ //@aux-build:proc_macros.rs -//@compile-flags: -Zdeduplicate-diagnostics=yes #![warn(clippy::ptr_as_ptr)] diff --git a/tests/ui/ptr_as_ptr.rs b/tests/ui/ptr_as_ptr.rs index 8f2068cd2684..7ab52e63da55 100644 --- a/tests/ui/ptr_as_ptr.rs +++ b/tests/ui/ptr_as_ptr.rs @@ -1,5 +1,4 @@ //@aux-build:proc_macros.rs -//@compile-flags: -Zdeduplicate-diagnostics=yes #![warn(clippy::ptr_as_ptr)] diff --git a/tests/ui/ptr_as_ptr.stderr b/tests/ui/ptr_as_ptr.stderr index e6cd697c7baf..e162f35baf55 100644 --- a/tests/ui/ptr_as_ptr.stderr +++ b/tests/ui/ptr_as_ptr.stderr @@ -1,5 +1,5 @@ error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:19:33 + --> tests/ui/ptr_as_ptr.rs:18:33 | LL | *unsafe { Box::from_raw(Box::into_raw(Box::new(o)) as *mut super::issue_11278_a::T) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `Box::into_raw(Box::new(o)).cast::>()` @@ -8,37 +8,37 @@ LL | *unsafe { Box::from_raw(Box::into_raw(Box::new(o)) as *mut super::i = help: to override `-D warnings` add `#[allow(clippy::ptr_as_ptr)]` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:28:13 + --> tests/ui/ptr_as_ptr.rs:27:13 | LL | let _ = ptr as *const i32; | ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:29:13 + --> tests/ui/ptr_as_ptr.rs:28:13 | LL | let _ = mut_ptr as *mut i32; | ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:34:17 + --> tests/ui/ptr_as_ptr.rs:33:17 | LL | let _ = *ptr_ptr as *const i32; | ^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `(*ptr_ptr).cast::()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:47:25 + --> tests/ui/ptr_as_ptr.rs:46:25 | LL | let _: *const i32 = ptr as *const _; | ^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:48:23 + --> tests/ui/ptr_as_ptr.rs:47:23 | LL | let _: *mut i32 = mut_ptr as _; | ^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:51:21 + --> tests/ui/ptr_as_ptr.rs:50:21 | LL | let _ = inline!($ptr as *const i32); | ^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `$ptr.cast::()` @@ -46,157 +46,157 @@ LL | let _ = inline!($ptr as *const i32); = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:72:13 + --> tests/ui/ptr_as_ptr.rs:71:13 | LL | let _ = ptr as *const i32; | ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:73:13 + --> tests/ui/ptr_as_ptr.rs:72:13 | LL | let _ = mut_ptr as *mut i32; | ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:80:9 + --> tests/ui/ptr_as_ptr.rs:79:9 | LL | ptr::null_mut() as *mut u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:84:9 + --> tests/ui/ptr_as_ptr.rs:83:9 | LL | std::ptr::null_mut() as *mut u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut::()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:89:9 + --> tests/ui/ptr_as_ptr.rs:88:9 | LL | ptr::null_mut() as *mut u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:93:9 + --> tests/ui/ptr_as_ptr.rs:92:9 | LL | core::ptr::null_mut() as *mut u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut::()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:98:9 + --> tests/ui/ptr_as_ptr.rs:97:9 | LL | ptr::null() as *const u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null::()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:102:9 + --> tests/ui/ptr_as_ptr.rs:101:9 | LL | std::ptr::null() as *const u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null::()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:107:9 + --> tests/ui/ptr_as_ptr.rs:106:9 | LL | ptr::null() as *const u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null::()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:111:9 + --> tests/ui/ptr_as_ptr.rs:110:9 | LL | core::ptr::null() as *const u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null::()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:118:9 + --> tests/ui/ptr_as_ptr.rs:117:9 | LL | ptr::null_mut() as *mut _ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:122:9 + --> tests/ui/ptr_as_ptr.rs:121:9 | LL | std::ptr::null_mut() as *mut _ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:127:9 + --> tests/ui/ptr_as_ptr.rs:126:9 | LL | ptr::null_mut() as *mut _ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:131:9 + --> tests/ui/ptr_as_ptr.rs:130:9 | LL | core::ptr::null_mut() as *mut _ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:136:9 + --> tests/ui/ptr_as_ptr.rs:135:9 | LL | ptr::null() as *const _ | ^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:140:9 + --> tests/ui/ptr_as_ptr.rs:139:9 | LL | std::ptr::null() as *const _ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:145:9 + --> tests/ui/ptr_as_ptr.rs:144:9 | LL | ptr::null() as *const _ | ^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:149:9 + --> tests/ui/ptr_as_ptr.rs:148:9 | LL | core::ptr::null() as *const _ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:156:9 + --> tests/ui/ptr_as_ptr.rs:155:9 | LL | ptr::null_mut() as _ | ^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:160:9 + --> tests/ui/ptr_as_ptr.rs:159:9 | LL | std::ptr::null_mut() as _ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:165:9 + --> tests/ui/ptr_as_ptr.rs:164:9 | LL | ptr::null_mut() as _ | ^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:169:9 + --> tests/ui/ptr_as_ptr.rs:168:9 | LL | core::ptr::null_mut() as _ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:174:9 + --> tests/ui/ptr_as_ptr.rs:173:9 | LL | ptr::null() as _ | ^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:178:9 + --> tests/ui/ptr_as_ptr.rs:177:9 | LL | std::ptr::null() as _ | ^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:183:9 + --> tests/ui/ptr_as_ptr.rs:182:9 | LL | ptr::null() as _ | ^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()` error: `as` casting between raw pointers without changing its mutability - --> tests/ui/ptr_as_ptr.rs:187:9 + --> tests/ui/ptr_as_ptr.rs:186:9 | LL | core::ptr::null() as _ | ^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()` diff --git a/tests/ui/search_is_some_fixable_none.fixed b/tests/ui/search_is_some_fixable_none.fixed index 51636392f2bc..86a937b4dae1 100644 --- a/tests/ui/search_is_some_fixable_none.fixed +++ b/tests/ui/search_is_some_fixable_none.fixed @@ -213,3 +213,53 @@ mod issue7392 { let _ = !v.iter().any(|fp| test_u32_2(*fp.field)); } } + +mod issue_11910 { + fn computations() -> u32 { + 0 + } + + struct Foo; + impl Foo { + fn bar(&self, _: bool) {} + } + + fn test_normal_for_iter() { + let v = vec![3, 2, 1, 0, -1, -2, -3]; + let _ = !v.iter().any(|x| *x == 42); + Foo.bar(!v.iter().any(|x| *x == 42)); + } + + fn test_then_for_iter() { + let v = vec![3, 2, 1, 0, -1, -2, -3]; + (!v.iter().any(|x| *x == 42)).then(computations); + } + + fn test_then_some_for_iter() { + let v = vec![3, 2, 1, 0, -1, -2, -3]; + (!v.iter().any(|x| *x == 42)).then_some(0); + } + + fn test_normal_for_str() { + let s = "hello"; + let _ = !s.contains("world"); + Foo.bar(!s.contains("world")); + let s = String::from("hello"); + let _ = !s.contains("world"); + Foo.bar(!s.contains("world")); + } + + fn test_then_for_str() { + let s = "hello"; + let _ = (!s.contains("world")).then(computations); + let s = String::from("hello"); + let _ = (!s.contains("world")).then(computations); + } + + fn test_then_some_for_str() { + let s = "hello"; + let _ = (!s.contains("world")).then_some(0); + let s = String::from("hello"); + let _ = (!s.contains("world")).then_some(0); + } +} diff --git a/tests/ui/search_is_some_fixable_none.rs b/tests/ui/search_is_some_fixable_none.rs index c7d773e18a32..c0103a015097 100644 --- a/tests/ui/search_is_some_fixable_none.rs +++ b/tests/ui/search_is_some_fixable_none.rs @@ -219,3 +219,53 @@ mod issue7392 { let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_none(); } } + +mod issue_11910 { + fn computations() -> u32 { + 0 + } + + struct Foo; + impl Foo { + fn bar(&self, _: bool) {} + } + + fn test_normal_for_iter() { + let v = vec![3, 2, 1, 0, -1, -2, -3]; + let _ = v.iter().find(|x| **x == 42).is_none(); + Foo.bar(v.iter().find(|x| **x == 42).is_none()); + } + + fn test_then_for_iter() { + let v = vec![3, 2, 1, 0, -1, -2, -3]; + v.iter().find(|x| **x == 42).is_none().then(computations); + } + + fn test_then_some_for_iter() { + let v = vec![3, 2, 1, 0, -1, -2, -3]; + v.iter().find(|x| **x == 42).is_none().then_some(0); + } + + fn test_normal_for_str() { + let s = "hello"; + let _ = s.find("world").is_none(); + Foo.bar(s.find("world").is_none()); + let s = String::from("hello"); + let _ = s.find("world").is_none(); + Foo.bar(s.find("world").is_none()); + } + + fn test_then_for_str() { + let s = "hello"; + let _ = s.find("world").is_none().then(computations); + let s = String::from("hello"); + let _ = s.find("world").is_none().then(computations); + } + + fn test_then_some_for_str() { + let s = "hello"; + let _ = s.find("world").is_none().then_some(0); + let s = String::from("hello"); + let _ = s.find("world").is_none().then_some(0); + } +} diff --git a/tests/ui/search_is_some_fixable_none.stderr b/tests/ui/search_is_some_fixable_none.stderr index 4ad1e2508c48..2c858b9fb10e 100644 --- a/tests/ui/search_is_some_fixable_none.stderr +++ b/tests/ui/search_is_some_fixable_none.stderr @@ -282,5 +282,77 @@ error: called `is_none()` after searching an `Iterator` with `find` LL | let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|fp| test_u32_2(*fp.field))` -error: aborting due to 43 previous errors +error: called `is_none()` after searching an `Iterator` with `find` + --> tests/ui/search_is_some_fixable_none.rs:235:17 + | +LL | let _ = v.iter().find(|x| **x == 42).is_none(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| *x == 42)` + +error: called `is_none()` after searching an `Iterator` with `find` + --> tests/ui/search_is_some_fixable_none.rs:236:17 + | +LL | Foo.bar(v.iter().find(|x| **x == 42).is_none()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| *x == 42)` + +error: called `is_none()` after searching an `Iterator` with `find` + --> tests/ui/search_is_some_fixable_none.rs:241:9 + | +LL | v.iter().find(|x| **x == 42).is_none().then(computations); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!v.iter().any(|x| *x == 42))` + +error: called `is_none()` after searching an `Iterator` with `find` + --> tests/ui/search_is_some_fixable_none.rs:246:9 + | +LL | v.iter().find(|x| **x == 42).is_none().then_some(0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!v.iter().any(|x| *x == 42))` + +error: called `is_none()` after calling `find()` on a string + --> tests/ui/search_is_some_fixable_none.rs:251:17 + | +LL | let _ = s.find("world").is_none(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s.contains("world")` + +error: called `is_none()` after calling `find()` on a string + --> tests/ui/search_is_some_fixable_none.rs:252:17 + | +LL | Foo.bar(s.find("world").is_none()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s.contains("world")` + +error: called `is_none()` after calling `find()` on a string + --> tests/ui/search_is_some_fixable_none.rs:254:17 + | +LL | let _ = s.find("world").is_none(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s.contains("world")` + +error: called `is_none()` after calling `find()` on a string + --> tests/ui/search_is_some_fixable_none.rs:255:17 + | +LL | Foo.bar(s.find("world").is_none()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s.contains("world")` + +error: called `is_none()` after calling `find()` on a string + --> tests/ui/search_is_some_fixable_none.rs:260:17 + | +LL | let _ = s.find("world").is_none().then(computations); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!s.contains("world"))` + +error: called `is_none()` after calling `find()` on a string + --> tests/ui/search_is_some_fixable_none.rs:262:17 + | +LL | let _ = s.find("world").is_none().then(computations); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!s.contains("world"))` + +error: called `is_none()` after calling `find()` on a string + --> tests/ui/search_is_some_fixable_none.rs:267:17 + | +LL | let _ = s.find("world").is_none().then_some(0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!s.contains("world"))` + +error: called `is_none()` after calling `find()` on a string + --> tests/ui/search_is_some_fixable_none.rs:269:17 + | +LL | let _ = s.find("world").is_none().then_some(0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!s.contains("world"))` + +error: aborting due to 55 previous errors diff --git a/tests/ui/unconditional_recursion.rs b/tests/ui/unconditional_recursion.rs index 70b390b00e27..a51fc567f50c 100644 --- a/tests/ui/unconditional_recursion.rs +++ b/tests/ui/unconditional_recursion.rs @@ -266,7 +266,7 @@ struct S13 { impl S13 { fn new() -> Self { - // Shoud not warn! + // Should not warn! Self::default() } } diff --git a/tests/ui/unnecessary_clippy_cfg.stderr b/tests/ui/unnecessary_clippy_cfg.stderr index fbc05743ca74..3d58c9eb5dae 100644 --- a/tests/ui/unnecessary_clippy_cfg.stderr +++ b/tests/ui/unnecessary_clippy_cfg.stderr @@ -57,5 +57,41 @@ error: no need to put clippy lints behind a `clippy` cfg LL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#![deny(clippy::non_minimal_cfg, clippy::maybe_misused_cfg)]` -error: aborting due to 8 previous errors +error: duplicated attribute + --> tests/ui/unnecessary_clippy_cfg.rs:8:26 + | +LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] + | ^^^^^^^^^ + | +note: first defined here + --> tests/ui/unnecessary_clippy_cfg.rs:6:26 + | +LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] + | ^^^^^^^^^ +help: remove this attribute + --> tests/ui/unnecessary_clippy_cfg.rs:8:26 + | +LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] + | ^^^^^^^^^ + = note: `-D clippy::duplicated-attributes` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::duplicated_attributes)]` + +error: duplicated attribute + --> tests/ui/unnecessary_clippy_cfg.rs:17:25 + | +LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] + | ^^^^^^^^^ + | +note: first defined here + --> tests/ui/unnecessary_clippy_cfg.rs:15:25 + | +LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] + | ^^^^^^^^^ +help: remove this attribute + --> tests/ui/unnecessary_clippy_cfg.rs:17:25 + | +LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] + | ^^^^^^^^^ + +error: aborting due to 10 previous errors diff --git a/tests/ui/useless_attribute.fixed b/tests/ui/useless_attribute.fixed index d1cdf73d559f..81759086f79e 100644 --- a/tests/ui/useless_attribute.fixed +++ b/tests/ui/useless_attribute.fixed @@ -1,6 +1,6 @@ //@aux-build:proc_macro_derive.rs -#![allow(unused)] +#![allow(unused, clippy::duplicated_attributes)] #![warn(clippy::useless_attribute)] #![warn(unreachable_pub)] #![feature(rustc_private)] diff --git a/tests/ui/useless_attribute.rs b/tests/ui/useless_attribute.rs index d6aa7fa242cf..59a9dcf093bc 100644 --- a/tests/ui/useless_attribute.rs +++ b/tests/ui/useless_attribute.rs @@ -1,6 +1,6 @@ //@aux-build:proc_macro_derive.rs -#![allow(unused)] +#![allow(unused, clippy::duplicated_attributes)] #![warn(clippy::useless_attribute)] #![warn(unreachable_pub)] #![feature(rustc_private)] diff --git a/triagebot.toml b/triagebot.toml index d8131044ff2e..901977da25be 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -19,7 +19,12 @@ new_pr = true [assign] contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md" -users_on_vacation = ["y21"] +users_on_vacation = [ + "y21", + "matthiaskrgr", + "giraffate", + "Centri3", +] [assign.owners] "/.github" = ["@flip1995"] From f7aef635c14c70b59b7d0b53c05ef5e8a4dae401 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Thu, 18 Apr 2024 17:05:07 +0000 Subject: [PATCH 013/279] Rework interior mutability detection --- book/src/lint_configuration.md | 5 +- clippy_config/src/conf.rs | 5 +- clippy_lints/src/copies.rs | 44 +++---- clippy_lints/src/mut_key.rs | 67 +++------- clippy_lints/src/non_copy_const.rs | 99 +++++--------- clippy_lints/src/trait_bounds.rs | 1 + clippy_utils/src/lib.rs | 6 +- clippy_utils/src/ty.rs | 124 ++++++++++++------ tests/ui-toml/mut_key/mut_key.rs | 8 ++ .../borrow_interior_mutable_const/traits.rs | 4 +- .../traits.stderr | 18 ++- .../declare_interior_mutable_const/traits.rs | 5 +- .../traits.stderr | 20 ++- tests/ui/mut_key.rs | 10 +- tests/ui/mut_key.stderr | 32 ++--- 15 files changed, 225 insertions(+), 223 deletions(-) diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 7cefa6852642..fe0e9b80b11e 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -506,13 +506,14 @@ The maximum byte size a `Future` can have, before it triggers the `clippy::large ## `ignore-interior-mutability` -A list of paths to types that should be treated like `Arc`, i.e. ignored but -for the generic parameters for determining interior mutability +A list of paths to types that should be treated as if they do not contain interior mutability **Default Value:** `["bytes::Bytes"]` --- **Affected lints:** +* [`borrow_interior_mutable_const`](https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const) +* [`declare_interior_mutable_const`](https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const) * [`ifs_same_cond`](https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond) * [`mutable_key_type`](https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 781282213cc4..bbce4180dc4d 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -467,10 +467,9 @@ define_Conf! { /// /// The maximum size of the `Err`-variant in a `Result` returned from a function (large_error_threshold: u64 = 128), - /// Lint: MUTABLE_KEY_TYPE, IFS_SAME_COND. + /// Lint: MUTABLE_KEY_TYPE, IFS_SAME_COND, BORROW_INTERIOR_MUTABLE_CONST, DECLARE_INTERIOR_MUTABLE_CONST. /// - /// A list of paths to types that should be treated like `Arc`, i.e. ignored but - /// for the generic parameters for determining interior mutability + /// A list of paths to types that should be treated as if they do not contain interior mutability (ignore_interior_mutability: Vec = Vec::from(["bytes::Bytes".into()])), /// Lint: UNINLINED_FORMAT_ARGS. /// diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index acdcb54be271..ccf1d9d6f8c0 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -1,15 +1,14 @@ use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then}; use clippy_utils::source::{first_line_of_span, indent_of, reindent_multiline, snippet, snippet_opt}; -use clippy_utils::ty::{is_interior_mut_ty, needs_ordered_drop}; +use clippy_utils::ty::{needs_ordered_drop, InteriorMut}; use clippy_utils::visitors::for_each_expr; use clippy_utils::{ - capture_local_usage, def_path_def_ids, eq_expr_value, find_binding_init, get_enclosing_block, hash_expr, hash_stmt, - if_sequence, is_else_clause, is_lint_allowed, path_to_local, search_same, ContainsName, HirEqInterExpr, SpanlessEq, + capture_local_usage, eq_expr_value, find_binding_init, get_enclosing_block, hash_expr, hash_stmt, if_sequence, + is_else_clause, is_lint_allowed, path_to_local, search_same, ContainsName, HirEqInterExpr, SpanlessEq, }; use core::iter; use core::ops::ControlFlow; use rustc_errors::Applicability; -use rustc_hir::def_id::DefIdSet; use rustc_hir::{intravisit, BinOpKind, Block, Expr, ExprKind, HirId, HirIdSet, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; @@ -159,40 +158,36 @@ declare_clippy_lint! { "`if` statement with shared code in all blocks" } -pub struct CopyAndPaste { +pub struct CopyAndPaste<'tcx> { ignore_interior_mutability: Vec, - ignored_ty_ids: DefIdSet, + interior_mut: InteriorMut<'tcx>, } -impl CopyAndPaste { +impl CopyAndPaste<'_> { pub fn new(ignore_interior_mutability: Vec) -> Self { Self { ignore_interior_mutability, - ignored_ty_ids: DefIdSet::new(), + interior_mut: InteriorMut::default(), } } } -impl_lint_pass!(CopyAndPaste => [ +impl_lint_pass!(CopyAndPaste<'_> => [ IFS_SAME_COND, SAME_FUNCTIONS_IN_IF_CONDITION, IF_SAME_THEN_ELSE, BRANCHES_SHARING_CODE ]); -impl<'tcx> LateLintPass<'tcx> for CopyAndPaste { +impl<'tcx> LateLintPass<'tcx> for CopyAndPaste<'tcx> { fn check_crate(&mut self, cx: &LateContext<'tcx>) { - for ignored_ty in &self.ignore_interior_mutability { - let path: Vec<&str> = ignored_ty.split("::").collect(); - for id in def_path_def_ids(cx, path.as_slice()) { - self.ignored_ty_ids.insert(id); - } - } + self.interior_mut = InteriorMut::new(cx, &self.ignore_interior_mutability); } + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if !expr.span.from_expansion() && matches!(expr.kind, ExprKind::If(..)) && !is_else_clause(cx.tcx, expr) { let (conds, blocks) = if_sequence(expr); - lint_same_cond(cx, &conds, &self.ignored_ty_ids); + lint_same_cond(cx, &conds, &mut self.interior_mut); lint_same_fns_in_if_cond(cx, &conds); let all_same = !is_lint_allowed(cx, IF_SAME_THEN_ELSE, expr.hir_id) && lint_if_same_then_else(cx, &conds, &blocks); @@ -570,13 +565,14 @@ fn check_for_warn_of_moved_symbol(cx: &LateContext<'_>, symbols: &[(HirId, Symbo }) } -fn method_caller_is_mutable(cx: &LateContext<'_>, caller_expr: &Expr<'_>, ignored_ty_ids: &DefIdSet) -> bool { +fn method_caller_is_mutable<'tcx>( + cx: &LateContext<'tcx>, + caller_expr: &Expr<'_>, + interior_mut: &mut InteriorMut<'tcx>, +) -> bool { let caller_ty = cx.typeck_results().expr_ty(caller_expr); - // Check if given type has inner mutability and was not set to ignored by the configuration - let is_inner_mut_ty = is_interior_mut_ty(cx, caller_ty) - && !matches!(caller_ty.ty_adt_def(), Some(adt) if ignored_ty_ids.contains(&adt.did())); - is_inner_mut_ty + interior_mut.is_interior_mut_ty(cx, caller_ty) || caller_ty.is_mutable_ptr() // `find_binding_init` will return the binding iff its not mutable || path_to_local(caller_expr) @@ -585,7 +581,7 @@ fn method_caller_is_mutable(cx: &LateContext<'_>, caller_expr: &Expr<'_>, ignore } /// Implementation of `IFS_SAME_COND`. -fn lint_same_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>], ignored_ty_ids: &DefIdSet) { +fn lint_same_cond<'tcx>(cx: &LateContext<'tcx>, conds: &[&Expr<'_>], interior_mut: &mut InteriorMut<'tcx>) { for (i, j) in search_same( conds, |e| hash_expr(cx, e), @@ -593,7 +589,7 @@ fn lint_same_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>], ignored_ty_ids: &De // Ignore eq_expr side effects iff one of the expression kind is a method call // and the caller is not a mutable, including inner mutable type. if let ExprKind::MethodCall(_, caller, _, _) = lhs.kind { - if method_caller_is_mutable(cx, caller, ignored_ty_ids) { + if method_caller_is_mutable(cx, caller, interior_mut) { false } else { SpanlessEq::new(cx).eq_expr(lhs, rhs) diff --git a/clippy_lints/src/mut_key.rs b/clippy_lints/src/mut_key.rs index 8c2f43c97f4d..2eb534da0925 100644 --- a/clippy_lints/src/mut_key.rs +++ b/clippy_lints/src/mut_key.rs @@ -1,7 +1,6 @@ use clippy_utils::diagnostics::span_lint; -use clippy_utils::ty::is_interior_mut_ty; -use clippy_utils::{def_path_def_ids, trait_ref_of_method}; -use rustc_data_structures::fx::FxHashSet; +use clippy_utils::trait_ref_of_method; +use clippy_utils::ty::InteriorMut; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, Ty}; @@ -23,27 +22,15 @@ declare_clippy_lint! { /// ### Known problems /// /// #### False Positives - /// It's correct to use a struct that contains interior mutability as a key, when its + /// It's correct to use a struct that contains interior mutability as a key when its /// implementation of `Hash` or `Ord` doesn't access any of the interior mutable types. /// However, this lint is unable to recognize this, so it will often cause false positives in - /// theses cases. The `bytes` crate is a great example of this. + /// these cases. /// /// #### False Negatives - /// For custom `struct`s/`enum`s, this lint is unable to check for interior mutability behind - /// indirection. For example, `struct BadKey<'a>(&'a Cell)` will be seen as immutable - /// and cause a false negative if its implementation of `Hash`/`Ord` accesses the `Cell`. - /// - /// This lint does check a few cases for indirection. Firstly, using some standard library - /// types (`Option`, `Result`, `Box`, `Rc`, `Arc`, `Vec`, `VecDeque`, `BTreeMap` and - /// `BTreeSet`) directly as keys (e.g. in `HashMap>, ()>`) **will** trigger the - /// lint, because the impls of `Hash`/`Ord` for these types directly call `Hash`/`Ord` on their - /// contained type. - /// - /// Secondly, the implementations of `Hash` and `Ord` for raw pointers (`*const T` or `*mut T`) - /// apply only to the **address** of the contained value. Therefore, interior mutability - /// behind raw pointers (e.g. in `HashSet<*mut Cell>`) can't impact the value of `Hash` - /// or `Ord`, and therefore will not trigger this link. For more info, see issue - /// [#6745](https://github.com/rust-lang/rust-clippy/issues/6745). + /// This lint does not follow raw pointers (`*const T` or `*mut T`) as `Hash` and `Ord` + /// apply only to the **address** of the contained value. This can cause false negatives for + /// custom collections that use raw pointers internally. /// /// ### Example /// ```no_run @@ -51,13 +38,12 @@ declare_clippy_lint! { /// use std::collections::HashSet; /// use std::hash::{Hash, Hasher}; /// use std::sync::atomic::AtomicUsize; - ///# #[allow(unused)] /// /// struct Bad(AtomicUsize); /// impl PartialEq for Bad { /// fn eq(&self, rhs: &Self) -> bool { /// .. - /// ; unimplemented!(); + /// # ; true /// } /// } /// @@ -66,7 +52,7 @@ declare_clippy_lint! { /// impl Hash for Bad { /// fn hash(&self, h: &mut H) { /// .. - /// ; unimplemented!(); + /// # ; /// } /// } /// @@ -80,25 +66,16 @@ declare_clippy_lint! { "Check for mutable `Map`/`Set` key type" } -#[derive(Clone)] -pub struct MutableKeyType { +pub struct MutableKeyType<'tcx> { ignore_interior_mutability: Vec, - ignore_mut_def_ids: FxHashSet, + interior_mut: InteriorMut<'tcx>, } -impl_lint_pass!(MutableKeyType => [ MUTABLE_KEY_TYPE ]); +impl_lint_pass!(MutableKeyType<'_> => [ MUTABLE_KEY_TYPE ]); -impl<'tcx> LateLintPass<'tcx> for MutableKeyType { +impl<'tcx> LateLintPass<'tcx> for MutableKeyType<'tcx> { fn check_crate(&mut self, cx: &LateContext<'tcx>) { - self.ignore_mut_def_ids.clear(); - let mut path = Vec::new(); - for ty in &self.ignore_interior_mutability { - path.extend(ty.split("::")); - for id in def_path_def_ids(cx, &path[..]) { - self.ignore_mut_def_ids.insert(id); - } - path.clear(); - } + self.interior_mut = InteriorMut::without_pointers(cx, &self.ignore_interior_mutability); } fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { @@ -121,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for MutableKeyType { } } - fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::LetStmt<'_>) { + fn check_local(&mut self, cx: &LateContext<'tcx>, local: &hir::LetStmt<'tcx>) { if let hir::PatKind::Wild = local.pat.kind { return; } @@ -129,15 +106,15 @@ impl<'tcx> LateLintPass<'tcx> for MutableKeyType { } } -impl MutableKeyType { +impl<'tcx> MutableKeyType<'tcx> { pub fn new(ignore_interior_mutability: Vec) -> Self { Self { ignore_interior_mutability, - ignore_mut_def_ids: FxHashSet::default(), + interior_mut: InteriorMut::default(), } } - fn check_sig(&self, cx: &LateContext<'_>, fn_def_id: LocalDefId, decl: &hir::FnDecl<'_>) { + fn check_sig(&mut self, cx: &LateContext<'tcx>, fn_def_id: LocalDefId, decl: &hir::FnDecl<'tcx>) { let fn_sig = cx.tcx.fn_sig(fn_def_id).instantiate_identity(); for (hir_ty, ty) in iter::zip(decl.inputs, fn_sig.inputs().skip_binder()) { self.check_ty_(cx, hir_ty.span, *ty); @@ -151,7 +128,7 @@ impl MutableKeyType { // We want to lint 1. sets or maps with 2. not immutable key types and 3. no unerased // generics (because the compiler cannot ensure immutability for unknown types). - fn check_ty_<'tcx>(&self, cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) { + fn check_ty_(&mut self, cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) { let ty = ty.peel_refs(); if let ty::Adt(def, args) = ty.kind() { let is_keyed_type = [sym::HashMap, sym::BTreeMap, sym::HashSet, sym::BTreeSet] @@ -162,11 +139,7 @@ impl MutableKeyType { } let subst_ty = args.type_at(0); - // Determines if a type contains interior mutability which would affect its implementation of - // [`Hash`] or [`Ord`]. - if is_interior_mut_ty(cx, subst_ty) - && !matches!(subst_ty.ty_adt_def(), Some(adt) if self.ignore_mut_def_ids.contains(&adt.did())) - { + if self.interior_mut.is_interior_mut_ty(cx, subst_ty) { span_lint(cx, MUTABLE_KEY_TYPE, span, "mutable key type"); } } diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index ff10a841aef1..76d9cee18aa7 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -5,9 +5,9 @@ use std::ptr; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::in_constant; use clippy_utils::macros::macro_backtrace; -use clippy_utils::{def_path_def_ids, in_constant}; -use rustc_data_structures::fx::FxHashSet; +use clippy_utils::ty::InteriorMut; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{ @@ -52,8 +52,8 @@ declare_clippy_lint! { /// There're other enums plus associated constants cases that the lint cannot handle. /// /// Types that have underlying or potential interior mutability trigger the lint whether - /// the interior mutable field is used or not. See issues - /// [#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and + /// the interior mutable field is used or not. See issue + /// [#5812](https://github.com/rust-lang/rust-clippy/issues/5812) /// /// ### Example /// ```no_run @@ -170,42 +170,22 @@ fn lint(cx: &LateContext<'_>, source: Source) { }); } -#[derive(Clone)] -pub struct NonCopyConst { +pub struct NonCopyConst<'tcx> { ignore_interior_mutability: Vec, - ignore_mut_def_ids: FxHashSet, + interior_mut: InteriorMut<'tcx>, } -impl_lint_pass!(NonCopyConst => [DECLARE_INTERIOR_MUTABLE_CONST, BORROW_INTERIOR_MUTABLE_CONST]); +impl_lint_pass!(NonCopyConst<'_> => [DECLARE_INTERIOR_MUTABLE_CONST, BORROW_INTERIOR_MUTABLE_CONST]); -impl NonCopyConst { +impl<'tcx> NonCopyConst<'tcx> { pub fn new(ignore_interior_mutability: Vec) -> Self { Self { ignore_interior_mutability, - ignore_mut_def_ids: FxHashSet::default(), + interior_mut: InteriorMut::default(), } } - fn is_ty_ignored(&self, ty: Ty<'_>) -> bool { - matches!(ty.ty_adt_def(), Some(adt) if self.ignore_mut_def_ids.contains(&adt.did())) - } - - fn is_unfrozen<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { - // Ignore types whose layout is unknown since `is_freeze` reports every generic types as `!Freeze`, - // making it indistinguishable from `UnsafeCell`. i.e. it isn't a tool to prove a type is - // 'unfrozen'. However, this code causes a false negative in which - // a type contains a layout-unknown type, but also an unsafe cell like `const CELL: Cell`. - // Yet, it's better than `ty.has_type_flags(TypeFlags::HAS_TY_PARAM | TypeFlags::HAS_PROJECTION)` - // since it works when a pointer indirection involves (`Cell<*const T>`). - // Making up a `ParamEnv` where every generic params and assoc types are `Freeze`is another option; - // but I'm not sure whether it's a decent way, if possible. - cx.tcx.layout_of(cx.param_env.and(ty)).is_ok() && !ty.is_freeze(cx.tcx, cx.param_env) - } - - fn is_value_unfrozen_raw_inner<'tcx>(&self, cx: &LateContext<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> bool { - if self.is_ty_ignored(ty) { - return false; - } + fn is_value_unfrozen_raw_inner(cx: &LateContext<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> bool { match *ty.kind() { // the fact that we have to dig into every structs to search enums // leads us to the point checking `UnsafeCell` directly is the only option. @@ -216,8 +196,7 @@ impl NonCopyConst { ty::Array(ty, _) => val .unwrap_branch() .iter() - .any(|field| self.is_value_unfrozen_raw_inner(cx, *field, ty)), - ty::Adt(def, _) if def.is_union() => false, + .any(|field| Self::is_value_unfrozen_raw_inner(cx, *field, ty)), ty::Adt(def, args) if def.is_enum() => { let (&variant_index, fields) = val.unwrap_branch().split_first().unwrap(); let variant_index = VariantIdx::from_u32(variant_index.unwrap_leaf().try_to_u32().ok().unwrap()); @@ -230,24 +209,23 @@ impl NonCopyConst { .iter() .map(|field| field.ty(cx.tcx, args)), ) - .any(|(field, ty)| self.is_value_unfrozen_raw_inner(cx, field, ty)) + .any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, field, ty)) }, ty::Adt(def, args) => val .unwrap_branch() .iter() .zip(def.non_enum_variant().fields.iter().map(|field| field.ty(cx.tcx, args))) - .any(|(field, ty)| self.is_value_unfrozen_raw_inner(cx, *field, ty)), + .any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, *field, ty)), ty::Tuple(tys) => val .unwrap_branch() .iter() .zip(tys) - .any(|(field, ty)| self.is_value_unfrozen_raw_inner(cx, *field, ty)), + .any(|(field, ty)| Self::is_value_unfrozen_raw_inner(cx, *field, ty)), _ => false, } } - fn is_value_unfrozen_raw<'tcx>( - &self, + fn is_value_unfrozen_raw( cx: &LateContext<'tcx>, result: Result>, ErrorHandled>, ty: Ty<'tcx>, @@ -277,11 +255,11 @@ impl NonCopyConst { // I chose this way because unfrozen enums as assoc consts are rare (or, hopefully, none). matches!(err, ErrorHandled::TooGeneric(..)) }, - |val| val.map_or(true, |val| self.is_value_unfrozen_raw_inner(cx, val, ty)), + |val| val.map_or(true, |val| Self::is_value_unfrozen_raw_inner(cx, val, ty)), ) } - fn is_value_unfrozen_poly<'tcx>(&self, cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<'tcx>) -> bool { + fn is_value_unfrozen_poly(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<'tcx>) -> bool { let def_id = body_id.hir_id.owner.to_def_id(); let args = ty::GenericArgs::identity_for_item(cx.tcx, def_id); let instance = ty::Instance::new(def_id, args); @@ -291,17 +269,17 @@ impl NonCopyConst { }; let param_env = cx.tcx.param_env(def_id).with_reveal_all_normalized(cx.tcx); let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, DUMMY_SP); - self.is_value_unfrozen_raw(cx, result, ty) + Self::is_value_unfrozen_raw(cx, result, ty) } - fn is_value_unfrozen_expr<'tcx>(&self, cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool { + fn is_value_unfrozen_expr(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool { let args = cx.typeck_results().node_args(hir_id); let result = Self::const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, args), DUMMY_SP); - self.is_value_unfrozen_raw(cx, result, ty) + Self::is_value_unfrozen_raw(cx, result, ty) } - pub fn const_eval_resolve<'tcx>( + pub fn const_eval_resolve( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ct: ty::UnevaluatedConst<'tcx>, @@ -321,26 +299,17 @@ impl NonCopyConst { } } -impl<'tcx> LateLintPass<'tcx> for NonCopyConst { +impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { fn check_crate(&mut self, cx: &LateContext<'tcx>) { - self.ignore_mut_def_ids.clear(); - let mut path = Vec::new(); - for ty in &self.ignore_interior_mutability { - path.extend(ty.split("::")); - for id in def_path_def_ids(cx, &path[..]) { - self.ignore_mut_def_ids.insert(id); - } - path.clear(); - } + self.interior_mut = InteriorMut::new(cx, &self.ignore_interior_mutability); } fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx Item<'_>) { if let ItemKind::Const(.., body_id) = it.kind { let ty = cx.tcx.type_of(it.owner_id).instantiate_identity(); if !ignored_macro(cx, it) - && !self.is_ty_ignored(ty) - && Self::is_unfrozen(cx, ty) - && self.is_value_unfrozen_poly(cx, body_id, ty) + && self.interior_mut.is_interior_mut_ty(cx, ty) + && Self::is_value_unfrozen_poly(cx, body_id, ty) { lint(cx, Source::Item { item: it.span }); } @@ -354,7 +323,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst { // Normalize assoc types because ones originated from generic params // bounded other traits could have their bound. let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty); - if !self.is_ty_ignored(ty) && Self::is_unfrozen(cx, normalized) + if self.interior_mut.is_interior_mut_ty(cx, normalized) // When there's no default value, lint it only according to its type; // in other words, lint consts whose value *could* be unfrozen, not definitely is. // This feels inconsistent with how the lint treats generic types, @@ -367,7 +336,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst { // i.e. having an enum doesn't necessary mean a type has a frozen variant. // And, implementing it isn't a trivial task; it'll probably end up // re-implementing the trait predicate evaluation specific to `Freeze`. - && body_id_opt.map_or(true, |body_id| self.is_value_unfrozen_poly(cx, body_id, normalized)) + && body_id_opt.map_or(true, |body_id| Self::is_value_unfrozen_poly(cx, body_id, normalized)) { lint(cx, Source::Assoc { item: trait_item.span }); } @@ -409,8 +378,8 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst { // e.g. `layout_of(...).is_err() || has_frozen_variant(...);` && let ty = cx.tcx.type_of(impl_item.owner_id).instantiate_identity() && let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty) - && !self.is_ty_ignored(ty) && Self::is_unfrozen(cx, normalized) - && self.is_value_unfrozen_poly(cx, *body_id, normalized) + && self.interior_mut.is_interior_mut_ty(cx, normalized) + && Self::is_value_unfrozen_poly(cx, *body_id, normalized) { lint(cx, Source::Assoc { item: impl_item.span }); } @@ -420,9 +389,8 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst { // Normalize assoc types originated from generic params. let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty); - if !self.is_ty_ignored(ty) - && Self::is_unfrozen(cx, ty) - && self.is_value_unfrozen_poly(cx, *body_id, normalized) + if self.interior_mut.is_interior_mut_ty(cx, normalized) + && Self::is_value_unfrozen_poly(cx, *body_id, normalized) { lint(cx, Source::Assoc { item: impl_item.span }); } @@ -517,9 +485,8 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst { cx.typeck_results().expr_ty(dereferenced_expr) }; - if !self.is_ty_ignored(ty) - && Self::is_unfrozen(cx, ty) - && self.is_value_unfrozen_expr(cx, expr.hir_id, item_def_id, ty) + if self.interior_mut.is_interior_mut_ty(cx, ty) + && Self::is_value_unfrozen_expr(cx, expr.hir_id, item_def_id, ty) { lint(cx, Source::Expr { expr: expr.span }); } diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs index 9468d367a926..c05cd9ed5934 100644 --- a/clippy_lints/src/trait_bounds.rs +++ b/clippy_lints/src/trait_bounds.rs @@ -237,6 +237,7 @@ impl TraitBounds { } } + #[allow(clippy::mutable_key_type)] fn check_type_repetition<'tcx>(&self, cx: &LateContext<'tcx>, gen: &'tcx Generics<'_>) { struct SpanlessTy<'cx, 'tcx> { ty: &'tcx Ty<'tcx>, diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index a13885b022f6..196ccf9df164 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -2328,10 +2328,10 @@ pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option(exprs: &[T], hash: Hash, eq: Eq) -> Vec<(&T, &T)> +pub fn search_same(exprs: &[T], mut hash: Hash, mut eq: Eq) -> Vec<(&T, &T)> where - Hash: Fn(&T) -> u64, - Eq: Fn(&T, &T) -> bool, + Hash: FnMut(&T) -> u64, + Eq: FnMut(&T, &T) -> bool, { match exprs { [a, b] if eq(a, b) => return vec![(a, b)], diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index a06a82c56530..23750ed4d1ba 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -29,9 +29,10 @@ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _ use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use rustc_trait_selection::traits::{Obligation, ObligationCause}; use std::assert_matches::debug_assert_matches; +use std::collections::hash_map::Entry; use std::iter; -use crate::{match_def_path, path_res}; +use crate::{def_path_def_ids, match_def_path, path_res}; mod type_certainty; pub use type_certainty::expr_type_is_certain; @@ -1198,47 +1199,88 @@ pub fn make_normalized_projection<'tcx>( helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, args)?) } -/// Check if given type has inner mutability such as [`std::cell::Cell`] or [`std::cell::RefCell`] -/// etc. -pub fn is_interior_mut_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { - match *ty.kind() { - ty::Ref(_, inner_ty, mutbl) => mutbl == Mutability::Mut || is_interior_mut_ty(cx, inner_ty), - ty::Slice(inner_ty) => is_interior_mut_ty(cx, inner_ty), - ty::Array(inner_ty, size) => { - size.try_eval_target_usize(cx.tcx, cx.param_env) - .map_or(true, |u| u != 0) - && is_interior_mut_ty(cx, inner_ty) - }, - ty::Tuple(fields) => fields.iter().any(|ty| is_interior_mut_ty(cx, ty)), - ty::Adt(def, args) => { - // Special case for collections in `std` who's impl of `Hash` or `Ord` delegates to - // that of their type parameters. Note: we don't include `HashSet` and `HashMap` - // because they have no impl for `Hash` or `Ord`. - let def_id = def.did(); - let is_std_collection = [ - sym::Option, - sym::Result, - sym::LinkedList, - sym::Vec, - sym::VecDeque, - sym::BTreeMap, - sym::BTreeSet, - sym::Rc, - sym::Arc, - ] +/// Helper to check if given type has inner mutability such as [`std::cell::Cell`] or +/// [`std::cell::RefCell`]. +#[derive(Default, Debug)] +pub struct InteriorMut<'tcx> { + ignored_def_ids: FxHashSet, + ignore_pointers: bool, + tys: FxHashMap, Option>, +} + +impl<'tcx> InteriorMut<'tcx> { + pub fn new(cx: &LateContext<'tcx>, ignore_interior_mutability: &[String]) -> Self { + let ignored_def_ids = ignore_interior_mutability .iter() - .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def_id)); - let is_box = Some(def_id) == cx.tcx.lang_items().owned_box(); - if is_std_collection || is_box { - // The type is mutable if any of its type parameters are - args.types().any(|ty| is_interior_mut_ty(cx, ty)) - } else { - !ty.has_escaping_bound_vars() - && cx.tcx.layout_of(cx.param_env.and(ty)).is_ok() - && !ty.is_freeze(cx.tcx, cx.param_env) - } - }, - _ => false, + .flat_map(|ignored_ty| { + let path: Vec<&str> = ignored_ty.split("::").collect(); + def_path_def_ids(cx, path.as_slice()) + }) + .collect(); + + Self { + ignored_def_ids, + ..Self::default() + } + } + + pub fn without_pointers(cx: &LateContext<'tcx>, ignore_interior_mutability: &[String]) -> Self { + Self { + ignore_pointers: true, + ..Self::new(cx, ignore_interior_mutability) + } + } + + /// Check if given type has inner mutability such as [`std::cell::Cell`] or + /// [`std::cell::RefCell`] etc. + pub fn is_interior_mut_ty(&mut self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { + match self.tys.entry(ty) { + Entry::Occupied(o) => return *o.get() == Some(true), + // Temporarily insert a `None` to break cycles + Entry::Vacant(v) => v.insert(None), + }; + + let interior_mut = match *ty.kind() { + ty::RawPtr(inner_ty, _) if !self.ignore_pointers => self.is_interior_mut_ty(cx, inner_ty), + ty::Ref(_, inner_ty, _) | ty::Slice(inner_ty) => self.is_interior_mut_ty(cx, inner_ty), + ty::Array(inner_ty, size) => { + size.try_eval_target_usize(cx.tcx, cx.param_env) + .map_or(true, |u| u != 0) + && self.is_interior_mut_ty(cx, inner_ty) + }, + ty::Tuple(fields) => fields.iter().any(|ty| self.is_interior_mut_ty(cx, ty)), + ty::Adt(def, _) if def.is_unsafe_cell() => true, + ty::Adt(def, args) => { + let is_std_collection = matches!( + cx.tcx.get_diagnostic_name(def.did()), + Some( + sym::LinkedList + | sym::Vec + | sym::VecDeque + | sym::BTreeMap + | sym::BTreeSet + | sym::HashMap + | sym::HashSet + | sym::Arc + | sym::Rc + ) + ); + + if is_std_collection || def.is_box() { + // Include the types from std collections that are behind pointers internally + args.types().any(|ty| self.is_interior_mut_ty(cx, ty)) + } else if self.ignored_def_ids.contains(&def.did()) || def.is_phantom_data() { + false + } else { + def.all_fields() + .any(|f| self.is_interior_mut_ty(cx, f.ty(cx.tcx, args))) + } + }, + _ => false, + }; + + self.tys.insert(ty, Some(interior_mut)); + interior_mut } } diff --git a/tests/ui-toml/mut_key/mut_key.rs b/tests/ui-toml/mut_key/mut_key.rs index 095e0d15448a..3a8e3741e20c 100644 --- a/tests/ui-toml/mut_key/mut_key.rs +++ b/tests/ui-toml/mut_key/mut_key.rs @@ -44,10 +44,18 @@ impl Deref for Counted { } } +#[derive(Hash, PartialEq, Eq)] +struct ContainsCounted { + inner: Counted, +} + // This is not linted because `"mut_key::Counted"` is in // `arc_like_types` in `clippy.toml` fn should_not_take_this_arg(_v: HashSet>) {} +fn indirect(_: HashMap) {} + fn main() { should_not_take_this_arg(HashSet::new()); + indirect(HashMap::new()); } diff --git a/tests/ui/borrow_interior_mutable_const/traits.rs b/tests/ui/borrow_interior_mutable_const/traits.rs index 4da3833cbf5a..5570e7cd6d2e 100644 --- a/tests/ui/borrow_interior_mutable_const/traits.rs +++ b/tests/ui/borrow_interior_mutable_const/traits.rs @@ -158,7 +158,7 @@ trait BothOfCellAndGeneric { const INDIRECT: Cell<*const T>; fn function() { - let _ = &Self::DIRECT; + let _ = &Self::DIRECT; //~ ERROR: interior mutability let _ = &Self::INDIRECT; //~ ERROR: interior mutability } } @@ -168,7 +168,7 @@ impl BothOfCellAndGeneric for Vec { const INDIRECT: Cell<*const T> = Cell::new(std::ptr::null()); fn function() { - let _ = &Self::DIRECT; + let _ = &Self::DIRECT; //~ ERROR: interior mutability let _ = &Self::INDIRECT; //~ ERROR: interior mutability } } diff --git a/tests/ui/borrow_interior_mutable_const/traits.stderr b/tests/ui/borrow_interior_mutable_const/traits.stderr index 582b744b49ff..8602b46b0dcf 100644 --- a/tests/ui/borrow_interior_mutable_const/traits.stderr +++ b/tests/ui/borrow_interior_mutable_const/traits.stderr @@ -75,6 +75,14 @@ LL | let _ = &Self::WRAPPED_SELF; | = help: assign this const to a local or static variable, and use the variable here +error: a `const` item with interior mutability should not be borrowed + --> tests/ui/borrow_interior_mutable_const/traits.rs:161:18 + | +LL | let _ = &Self::DIRECT; + | ^^^^^^^^^^^^ + | + = help: assign this const to a local or static variable, and use the variable here + error: a `const` item with interior mutability should not be borrowed --> tests/ui/borrow_interior_mutable_const/traits.rs:162:18 | @@ -83,6 +91,14 @@ LL | let _ = &Self::INDIRECT; | = help: assign this const to a local or static variable, and use the variable here +error: a `const` item with interior mutability should not be borrowed + --> tests/ui/borrow_interior_mutable_const/traits.rs:171:18 + | +LL | let _ = &Self::DIRECT; + | ^^^^^^^^^^^^ + | + = help: assign this const to a local or static variable, and use the variable here + error: a `const` item with interior mutability should not be borrowed --> tests/ui/borrow_interior_mutable_const/traits.rs:172:18 | @@ -123,5 +139,5 @@ LL | assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); | = help: assign this const to a local or static variable, and use the variable here -error: aborting due to 15 previous errors +error: aborting due to 17 previous errors diff --git a/tests/ui/declare_interior_mutable_const/traits.rs b/tests/ui/declare_interior_mutable_const/traits.rs index adc53891ef54..490073f97fb1 100644 --- a/tests/ui/declare_interior_mutable_const/traits.rs +++ b/tests/ui/declare_interior_mutable_const/traits.rs @@ -121,13 +121,12 @@ impl SelfType for AtomicUsize { // Even though a constant contains a generic type, if it also have an interior mutable type, // it should be linted at the definition site. trait BothOfCellAndGeneric { - // this is a false negative in the current implementation. - const DIRECT: Cell; + const DIRECT: Cell; //~ ERROR: interior mutable const INDIRECT: Cell<*const T>; //~ ERROR: interior mutable } impl BothOfCellAndGeneric for u64 { - const DIRECT: Cell = Cell::new(T::DEFAULT); + const DIRECT: Cell = Cell::new(T::DEFAULT); //~ ERROR: interior mutable const INDIRECT: Cell<*const T> = Cell::new(std::ptr::null()); } diff --git a/tests/ui/declare_interior_mutable_const/traits.stderr b/tests/ui/declare_interior_mutable_const/traits.stderr index 328453efa244..1d1e9e2002fa 100644 --- a/tests/ui/declare_interior_mutable_const/traits.stderr +++ b/tests/ui/declare_interior_mutable_const/traits.stderr @@ -55,22 +55,34 @@ LL | const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:126:5 + --> tests/ui/declare_interior_mutable_const/traits.rs:124:5 + | +LL | const DIRECT: Cell; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: a `const` item should never be interior mutable + --> tests/ui/declare_interior_mutable_const/traits.rs:125:5 | LL | const INDIRECT: Cell<*const T>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:142:5 + --> tests/ui/declare_interior_mutable_const/traits.rs:129:5 + | +LL | const DIRECT: Cell = Cell::new(T::DEFAULT); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: a `const` item should never be interior mutable + --> tests/ui/declare_interior_mutable_const/traits.rs:141:5 | LL | const ATOMIC: AtomicUsize = AtomicUsize::new(18); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: a `const` item should never be interior mutable - --> tests/ui/declare_interior_mutable_const/traits.rs:148:5 + --> tests/ui/declare_interior_mutable_const/traits.rs:147:5 | LL | const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 11 previous errors +error: aborting due to 13 previous errors diff --git a/tests/ui/mut_key.rs b/tests/ui/mut_key.rs index 2d70bfd4c770..81d8732b3b21 100644 --- a/tests/ui/mut_key.rs +++ b/tests/ui/mut_key.rs @@ -5,7 +5,7 @@ use std::rc::Rc; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering::Relaxed; use std::sync::Arc; -//@no-rustfix + struct Key(AtomicUsize); impl Clone for Key { @@ -77,8 +77,6 @@ fn main() { //~^ ERROR: mutable key type let _map = HashMap::<&mut Cell, usize>::new(); //~^ ERROR: mutable key type - let _map = HashMap::<&mut usize, usize>::new(); - //~^ ERROR: mutable key type // Collection types from `std` who's impl of `Hash` or `Ord` delegate their type parameters let _map = HashMap::>, usize>::new(); //~^ ERROR: mutable key type @@ -92,8 +90,6 @@ fn main() { //~^ ERROR: mutable key type let _map = HashMap::>>, usize>::new(); //~^ ERROR: mutable key type - let _map = HashMap::, usize>::new(); - //~^ ERROR: mutable key type // Smart pointers from `std` who's impl of `Hash` or `Ord` delegate their type parameters let _map = HashMap::>, usize>::new(); //~^ ERROR: mutable key type @@ -101,4 +97,8 @@ fn main() { //~^ ERROR: mutable key type let _map = HashMap::>, usize>::new(); //~^ ERROR: mutable key type + + // Not interior mutability + let _map = HashMap::<&mut usize, usize>::new(); + let _map = HashMap::, usize>::new(); } diff --git a/tests/ui/mut_key.stderr b/tests/ui/mut_key.stderr index e54c3075d4f1..5ad9aad2d0a5 100644 --- a/tests/ui/mut_key.stderr +++ b/tests/ui/mut_key.stderr @@ -38,70 +38,58 @@ LL | let _map = HashMap::<&mut Cell, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> tests/ui/mut_key.rs:80:5 - | -LL | let _map = HashMap::<&mut usize, usize>::new(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: mutable key type - --> tests/ui/mut_key.rs:83:5 + --> tests/ui/mut_key.rs:81:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> tests/ui/mut_key.rs:85:5 + --> tests/ui/mut_key.rs:83:5 | LL | let _map = HashMap::, ()>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> tests/ui/mut_key.rs:87:5 + --> tests/ui/mut_key.rs:85:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> tests/ui/mut_key.rs:89:5 + --> tests/ui/mut_key.rs:87:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> tests/ui/mut_key.rs:91:5 + --> tests/ui/mut_key.rs:89:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> tests/ui/mut_key.rs:93:5 + --> tests/ui/mut_key.rs:91:5 | LL | let _map = HashMap::>>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> tests/ui/mut_key.rs:95:5 - | -LL | let _map = HashMap::, usize>::new(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: mutable key type - --> tests/ui/mut_key.rs:98:5 + --> tests/ui/mut_key.rs:94:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> tests/ui/mut_key.rs:100:5 + --> tests/ui/mut_key.rs:96:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: mutable key type - --> tests/ui/mut_key.rs:102:5 + --> tests/ui/mut_key.rs:98:5 | LL | let _map = HashMap::>, usize>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 17 previous errors +error: aborting due to 15 previous errors From 26484cefb6e93b81ceed576a78db78f2c9ebe7fe Mon Sep 17 00:00:00 2001 From: Dominik Stolz Date: Wed, 17 Apr 2024 23:40:03 +0200 Subject: [PATCH 014/279] Disallow ambiguous attributes on expressions --- tests/ui/cfg_attr_rustfmt.fixed | 6 +++--- tests/ui/cfg_attr_rustfmt.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/ui/cfg_attr_rustfmt.fixed b/tests/ui/cfg_attr_rustfmt.fixed index 05d5b3d10eaf..84dac431169a 100644 --- a/tests/ui/cfg_attr_rustfmt.fixed +++ b/tests/ui/cfg_attr_rustfmt.fixed @@ -16,7 +16,7 @@ fn foo( fn skip_on_statements() { #[rustfmt::skip] - 5+3; + { 5+3; } } #[rustfmt::skip] @@ -33,11 +33,11 @@ mod foo { #[clippy::msrv = "1.29"] fn msrv_1_29() { #[cfg_attr(rustfmt, rustfmt::skip)] - 1+29; + { 1+29; } } #[clippy::msrv = "1.30"] fn msrv_1_30() { #[rustfmt::skip] - 1+30; + { 1+30; } } diff --git a/tests/ui/cfg_attr_rustfmt.rs b/tests/ui/cfg_attr_rustfmt.rs index bc29e20210e8..4ab5c70e13b5 100644 --- a/tests/ui/cfg_attr_rustfmt.rs +++ b/tests/ui/cfg_attr_rustfmt.rs @@ -16,7 +16,7 @@ fn foo( fn skip_on_statements() { #[cfg_attr(rustfmt, rustfmt::skip)] - 5+3; + { 5+3; } } #[cfg_attr(rustfmt, rustfmt_skip)] @@ -33,11 +33,11 @@ mod foo { #[clippy::msrv = "1.29"] fn msrv_1_29() { #[cfg_attr(rustfmt, rustfmt::skip)] - 1+29; + { 1+29; } } #[clippy::msrv = "1.30"] fn msrv_1_30() { #[cfg_attr(rustfmt, rustfmt::skip)] - 1+30; + { 1+30; } } From 2a4dae368c109d0029e12787a78b6c028b61ca08 Mon Sep 17 00:00:00 2001 From: Caio Date: Thu, 18 Apr 2024 17:24:47 -0300 Subject: [PATCH 015/279] [arithmetic_side_effects] Fix #12318 --- .../src/operators/arithmetic_side_effects.rs | 53 +++++++++++++------ tests/ui/arithmetic_side_effects.rs | 10 ++++ tests/ui/arithmetic_side_effects.stderr | 14 ++++- 3 files changed, 61 insertions(+), 16 deletions(-) diff --git a/clippy_lints/src/operators/arithmetic_side_effects.rs b/clippy_lints/src/operators/arithmetic_side_effects.rs index 96ea063aa74d..7d6f26cde3e9 100644 --- a/clippy_lints/src/operators/arithmetic_side_effects.rs +++ b/clippy_lints/src/operators/arithmetic_side_effects.rs @@ -7,14 +7,13 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, Ty}; use rustc_session::impl_lint_pass; -use rustc_span::source_map::Spanned; use rustc_span::symbol::sym; use rustc_span::{Span, Symbol}; use {rustc_ast as ast, rustc_hir as hir}; const HARD_CODED_ALLOWED_BINARY: &[[&str; 2]] = &[["f32", "f32"], ["f64", "f64"], ["std::string::String", "str"]]; const HARD_CODED_ALLOWED_UNARY: &[&str] = &["f32", "f64", "std::num::Saturating", "std::num::Wrapping"]; -const INTEGER_METHODS: &[Symbol] = &[ +const DISALLOWED_INT_METHODS: &[Symbol] = &[ sym::saturating_div, sym::wrapping_div, sym::wrapping_rem, @@ -27,8 +26,8 @@ pub struct ArithmeticSideEffects { allowed_unary: FxHashSet, // Used to check whether expressions are constants, such as in enum discriminants and consts const_span: Option, + disallowed_int_methods: FxHashSet, expr_span: Option, - integer_methods: FxHashSet, } impl_lint_pass!(ArithmeticSideEffects => [ARITHMETIC_SIDE_EFFECTS]); @@ -53,8 +52,8 @@ impl ArithmeticSideEffects { allowed_binary, allowed_unary, const_span: None, + disallowed_int_methods: DISALLOWED_INT_METHODS.iter().copied().collect(), expr_span: None, - integer_methods: INTEGER_METHODS.iter().copied().collect(), } } @@ -91,10 +90,10 @@ impl ArithmeticSideEffects { fn has_specific_allowed_type_and_operation<'tcx>( cx: &LateContext<'tcx>, lhs_ty: Ty<'tcx>, - op: &Spanned, + op: hir::BinOpKind, rhs_ty: Ty<'tcx>, ) -> bool { - let is_div_or_rem = matches!(op.node, hir::BinOpKind::Div | hir::BinOpKind::Rem); + let is_div_or_rem = matches!(op, hir::BinOpKind::Div | hir::BinOpKind::Rem); let is_non_zero_u = |cx: &LateContext<'tcx>, ty: Ty<'tcx>| { let tcx = cx.tcx; @@ -166,13 +165,35 @@ impl ArithmeticSideEffects { None } + /// Methods like `add_assign` are send to their `BinOps` references. + fn manage_sugar_methods<'tcx>( + &mut self, + cx: &LateContext<'tcx>, + expr: &'tcx hir::Expr<'_>, + lhs: &'tcx hir::Expr<'_>, + ps: &hir::PathSegment<'_>, + rhs: &'tcx hir::Expr<'_>, + ) { + if ps.ident.name == sym::add || ps.ident.name == sym::add_assign { + self.manage_bin_ops(cx, expr, hir::BinOpKind::Add, lhs, rhs); + } else if ps.ident.name == sym::div || ps.ident.name == sym::div_assign { + self.manage_bin_ops(cx, expr, hir::BinOpKind::Div, lhs, rhs); + } else if ps.ident.name == sym::mul || ps.ident.name == sym::mul_assign { + self.manage_bin_ops(cx, expr, hir::BinOpKind::Mul, lhs, rhs); + } else if ps.ident.name == sym::rem || ps.ident.name == sym::rem_assign { + self.manage_bin_ops(cx, expr, hir::BinOpKind::Rem, lhs, rhs); + } else if ps.ident.name == sym::sub || ps.ident.name == sym::sub_assign { + self.manage_bin_ops(cx, expr, hir::BinOpKind::Sub, lhs, rhs); + } + } + /// Manages when the lint should be triggered. Operations in constant environments, hard coded - /// types, custom allowed types and non-constant operations that won't overflow are ignored. + /// types, custom allowed types and non-constant operations that don't overflow are ignored. fn manage_bin_ops<'tcx>( &mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, - op: &Spanned, + op: hir::BinOpKind, lhs: &'tcx hir::Expr<'_>, rhs: &'tcx hir::Expr<'_>, ) { @@ -180,7 +201,7 @@ impl ArithmeticSideEffects { return; } if !matches!( - op.node, + op, hir::BinOpKind::Add | hir::BinOpKind::Div | hir::BinOpKind::Mul @@ -204,7 +225,7 @@ impl ArithmeticSideEffects { return; } let has_valid_op = if Self::is_integral(lhs_ty) && Self::is_integral(rhs_ty) { - if let hir::BinOpKind::Shl | hir::BinOpKind::Shr = op.node { + if let hir::BinOpKind::Shl | hir::BinOpKind::Shr = op { // At least for integers, shifts are already handled by the CTFE return; } @@ -213,7 +234,7 @@ impl ArithmeticSideEffects { Self::literal_integer(cx, actual_rhs), ) { (None, None) => false, - (None, Some(n)) => match (&op.node, n) { + (None, Some(n)) => match (&op, n) { // Division and module are always valid if applied to non-zero integers (hir::BinOpKind::Div | hir::BinOpKind::Rem, local_n) if local_n != 0 => true, // Adding or subtracting zeros is always a no-op @@ -223,7 +244,7 @@ impl ArithmeticSideEffects { => true, _ => false, }, - (Some(n), None) => match (&op.node, n) { + (Some(n), None) => match (&op, n) { // Adding or subtracting zeros is always a no-op (hir::BinOpKind::Add | hir::BinOpKind::Sub, 0) // Multiplication by 1 or 0 will never overflow @@ -249,6 +270,7 @@ impl ArithmeticSideEffects { &mut self, args: &'tcx [hir::Expr<'_>], cx: &LateContext<'tcx>, + expr: &'tcx hir::Expr<'_>, ps: &'tcx hir::PathSegment<'_>, receiver: &'tcx hir::Expr<'_>, ) { @@ -262,7 +284,8 @@ impl ArithmeticSideEffects { if !Self::is_integral(instance_ty) { return; } - if !self.integer_methods.contains(&ps.ident.name) { + self.manage_sugar_methods(cx, expr, receiver, ps, arg); + if !self.disallowed_int_methods.contains(&ps.ident.name) { return; } let (actual_arg, _) = peel_hir_expr_refs(arg); @@ -310,10 +333,10 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects { } match &expr.kind { hir::ExprKind::AssignOp(op, lhs, rhs) | hir::ExprKind::Binary(op, lhs, rhs) => { - self.manage_bin_ops(cx, expr, op, lhs, rhs); + self.manage_bin_ops(cx, expr, op.node, lhs, rhs); }, hir::ExprKind::MethodCall(ps, receiver, args, _) => { - self.manage_method_call(args, cx, ps, receiver); + self.manage_method_call(args, cx, expr, ps, receiver); }, hir::ExprKind::Unary(un_op, un_expr) => { self.manage_unary_ops(cx, expr, un_expr, *un_op); diff --git a/tests/ui/arithmetic_side_effects.rs b/tests/ui/arithmetic_side_effects.rs index b454c29aef4d..e6951826b2f3 100644 --- a/tests/ui/arithmetic_side_effects.rs +++ b/tests/ui/arithmetic_side_effects.rs @@ -521,4 +521,14 @@ pub fn issue_11393() { example_rem(x, maybe_zero); } +pub fn issue_12318() { + use core::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign}; + let mut one: i32 = 1; + one.add_assign(1); + one.div_assign(1); + one.mul_assign(1); + one.rem_assign(1); + one.sub_assign(1); +} + fn main() {} diff --git a/tests/ui/arithmetic_side_effects.stderr b/tests/ui/arithmetic_side_effects.stderr index 741c892a52cf..8039c0bfa248 100644 --- a/tests/ui/arithmetic_side_effects.stderr +++ b/tests/ui/arithmetic_side_effects.stderr @@ -715,5 +715,17 @@ error: arithmetic operation that can potentially result in unexpected side-effec LL | x % maybe_zero | ^^^^^^^^^^^^^^ -error: aborting due to 119 previous errors +error: arithmetic operation that can potentially result in unexpected side-effects + --> tests/ui/arithmetic_side_effects.rs:527:5 + | +LL | one.add_assign(1); + | ^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> tests/ui/arithmetic_side_effects.rs:531:5 + | +LL | one.sub_assign(1); + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 121 previous errors From 2f8b1e3eea2c513a14f9ce89118d94f5d534ea7b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 18 Apr 2024 22:20:42 +0200 Subject: [PATCH 016/279] needless_pass_by_ref_mut: Fix corner case in async functions --- clippy_lints/src/needless_pass_by_ref_mut.rs | 24 ++++++++++++++------ tests/ui/needless_pass_by_ref_mut2.fixed | 24 ++++++++++++++++++++ tests/ui/needless_pass_by_ref_mut2.rs | 24 ++++++++++++++++++++ tests/ui/needless_pass_by_ref_mut2.stderr | 20 ++++++++++++++++ 4 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 tests/ui/needless_pass_by_ref_mut2.fixed create mode 100644 tests/ui/needless_pass_by_ref_mut2.rs create mode 100644 tests/ui/needless_pass_by_ref_mut2.stderr diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs index 30d3e86dc4ed..c3ceb994f60b 100644 --- a/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -185,7 +185,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { } // Collect variables mutably used and spans which will need dereferencings from the // function body. - let MutablyUsedVariablesCtxt { mutably_used_vars, .. } = { + let mutably_used_vars = { let mut ctx = MutablyUsedVariablesCtxt { mutably_used_vars: HirIdSet::default(), prev_bind: None, @@ -217,7 +217,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { check_closures(&mut ctx, cx, &infcx, &mut checked_closures, async_closures); } } - ctx + ctx.generate_mutably_used_ids_from_aliases() }; for ((&input, &_), arg) in it { // Only take `&mut` arguments. @@ -309,14 +309,24 @@ struct MutablyUsedVariablesCtxt<'tcx> { } impl<'tcx> MutablyUsedVariablesCtxt<'tcx> { - fn add_mutably_used_var(&mut self, mut used_id: HirId) { - while let Some(id) = self.aliases.get(&used_id) { - self.mutably_used_vars.insert(used_id); - used_id = *id; - } + fn add_mutably_used_var(&mut self, used_id: HirId) { self.mutably_used_vars.insert(used_id); } + // Because the alias may come after the mutable use of a variable, we need to fill the map at + // the end. + fn generate_mutably_used_ids_from_aliases(mut self) -> HirIdSet { + let all_ids = self.mutably_used_vars.iter().copied().collect::>(); + for mut used_id in all_ids { + while let Some(id) = self.aliases.get(&used_id) { + self.mutably_used_vars.insert(used_id); + used_id = *id; + } + self.mutably_used_vars.insert(used_id); + } + self.mutably_used_vars + } + fn would_be_alias_cycle(&self, alias: HirId, mut target: HirId) -> bool { while let Some(id) = self.aliases.get(&target) { if *id == alias { diff --git a/tests/ui/needless_pass_by_ref_mut2.fixed b/tests/ui/needless_pass_by_ref_mut2.fixed new file mode 100644 index 000000000000..3c2576213cd7 --- /dev/null +++ b/tests/ui/needless_pass_by_ref_mut2.fixed @@ -0,0 +1,24 @@ +// If both `inner_async3` and `inner_async4` are present, aliases are declared after +// they're used in `inner_async4` for some reasons... This test ensures that no +// only `v` is marked as not used mutably in `inner_async4`. + +#![allow(clippy::redundant_closure_call)] +#![warn(clippy::needless_pass_by_ref_mut)] + +pub async fn inner_async3(x: &i32, y: &mut u32) { + //~^ ERROR: this argument is a mutable reference, but not used mutably + async { + *y += 1; + } + .await; +} + +pub async fn inner_async4(u: &mut i32, v: &u32) { + //~^ ERROR: this argument is a mutable reference, but not used mutably + async { + *u += 1; + } + .await; +} + +fn main() {} diff --git a/tests/ui/needless_pass_by_ref_mut2.rs b/tests/ui/needless_pass_by_ref_mut2.rs new file mode 100644 index 000000000000..34b0b564deb8 --- /dev/null +++ b/tests/ui/needless_pass_by_ref_mut2.rs @@ -0,0 +1,24 @@ +// If both `inner_async3` and `inner_async4` are present, aliases are declared after +// they're used in `inner_async4` for some reasons... This test ensures that no +// only `v` is marked as not used mutably in `inner_async4`. + +#![allow(clippy::redundant_closure_call)] +#![warn(clippy::needless_pass_by_ref_mut)] + +pub async fn inner_async3(x: &mut i32, y: &mut u32) { + //~^ ERROR: this argument is a mutable reference, but not used mutably + async { + *y += 1; + } + .await; +} + +pub async fn inner_async4(u: &mut i32, v: &mut u32) { + //~^ ERROR: this argument is a mutable reference, but not used mutably + async { + *u += 1; + } + .await; +} + +fn main() {} diff --git a/tests/ui/needless_pass_by_ref_mut2.stderr b/tests/ui/needless_pass_by_ref_mut2.stderr new file mode 100644 index 000000000000..c87536032256 --- /dev/null +++ b/tests/ui/needless_pass_by_ref_mut2.stderr @@ -0,0 +1,20 @@ +error: this argument is a mutable reference, but not used mutably + --> tests/ui/needless_pass_by_ref_mut2.rs:8:30 + | +LL | pub async fn inner_async3(x: &mut i32, y: &mut u32) { + | ^^^^^^^^ help: consider changing to: `&i32` + | + = warning: changing this function will impact semver compatibility + = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]` + +error: this argument is a mutable reference, but not used mutably + --> tests/ui/needless_pass_by_ref_mut2.rs:16:43 + | +LL | pub async fn inner_async4(u: &mut i32, v: &mut u32) { + | ^^^^^^^^ help: consider changing to: `&u32` + | + = warning: changing this function will impact semver compatibility + +error: aborting due to 2 previous errors + From 0999867ec5036b55825c3bb94f0820dde1e61e6a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 18 Apr 2024 22:24:55 +0200 Subject: [PATCH 017/279] needless_pass_by_ref_mut: emit the lint on `self` as well --- clippy_lints/src/needless_pass_by_ref_mut.rs | 4 +- tests/ui/needless_pass_by_ref_mut.rs | 42 +++++++-- tests/ui/needless_pass_by_ref_mut.stderr | 98 ++++++++++++-------- 3 files changed, 96 insertions(+), 48 deletions(-) diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs index c3ceb994f60b..9e47c3ad0b7f 100644 --- a/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -83,7 +83,9 @@ fn should_skip<'tcx>( } if is_self(arg) { - return true; + // Interestingly enough, `self` arguments make `is_from_proc_macro` return `true`, hence why + // we return early here. + return false; } if let PatKind::Binding(.., name, _) = arg.pat.kind { diff --git a/tests/ui/needless_pass_by_ref_mut.rs b/tests/ui/needless_pass_by_ref_mut.rs index a92197fb0af5..3f5f55f40020 100644 --- a/tests/ui/needless_pass_by_ref_mut.rs +++ b/tests/ui/needless_pass_by_ref_mut.rs @@ -44,18 +44,13 @@ fn non_mut_ref(_: &Vec) {} struct Bar; impl Bar { - // Should not warn on `&mut self`. fn bar(&mut self) {} + //~^ ERROR: this argument is a mutable reference, but not used mutably fn mushroom(&self, vec: &mut Vec) -> usize { //~^ ERROR: this argument is a mutable reference, but not used mutably vec.len() } - - fn badger(&mut self, vec: &mut Vec) -> usize { - //~^ ERROR: this argument is a mutable reference, but not used mutably - vec.len() - } } trait Babar { @@ -307,6 +302,41 @@ fn filter_copy(predicate: &mut impl FnMut(T) -> bool) -> impl FnMut(&T) move |&item| predicate(item) } +trait MutSelfTrait { + // Should not warn since it's a trait method. + fn mut_self(&mut self); +} + +struct MutSelf { + a: u32, +} + +impl MutSelf { + fn bar(&mut self) {} + //~^ ERROR: this argument is a mutable reference, but not used mutably + async fn foo(&mut self, u: &mut i32, v: &mut u32) { + //~^ ERROR: this argument is a mutable reference, but not used mutably + //~| ERROR: this argument is a mutable reference, but not used mutably + async { + *u += 1; + } + .await; + } + async fn foo2(&mut self, u: &mut i32, v: &mut u32) { + //~^ ERROR: this argument is a mutable reference, but not used mutably + async { + self.a += 1; + *u += 1; + } + .await; + } +} + +impl MutSelfTrait for MutSelf { + // Should not warn since it's a trait method. + fn mut_self(&mut self) {} +} + // `is_from_proc_macro` stress tests fn _empty_tup(x: &mut (())) {} fn _single_tup(x: &mut ((i32,))) {} diff --git a/tests/ui/needless_pass_by_ref_mut.stderr b/tests/ui/needless_pass_by_ref_mut.stderr index 89dad3e60b14..21ca393dcb63 100644 --- a/tests/ui/needless_pass_by_ref_mut.stderr +++ b/tests/ui/needless_pass_by_ref_mut.stderr @@ -13,6 +13,12 @@ error: this argument is a mutable reference, but not used mutably LL | fn foo6(s: &mut Vec) { | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` +error: this argument is a mutable reference, but not used mutably + --> tests/ui/needless_pass_by_ref_mut.rs:47:12 + | +LL | fn bar(&mut self) {} + | ^^^^^^^^^ help: consider changing to: `&self` + error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:50:29 | @@ -20,67 +26,61 @@ LL | fn mushroom(&self, vec: &mut Vec) -> usize { | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:55:31 - | -LL | fn badger(&mut self, vec: &mut Vec) -> usize { - | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` - -error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:132:16 + --> tests/ui/needless_pass_by_ref_mut.rs:127:16 | LL | async fn a1(x: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:136:16 + --> tests/ui/needless_pass_by_ref_mut.rs:131:16 | LL | async fn a2(x: &mut i32, y: String) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:140:16 + --> tests/ui/needless_pass_by_ref_mut.rs:135:16 | LL | async fn a3(x: &mut i32, y: String, z: String) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:144:16 + --> tests/ui/needless_pass_by_ref_mut.rs:139:16 | LL | async fn a4(x: &mut i32, y: i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:148:24 + --> tests/ui/needless_pass_by_ref_mut.rs:143:24 | LL | async fn a5(x: i32, y: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:152:24 + --> tests/ui/needless_pass_by_ref_mut.rs:147:24 | LL | async fn a6(x: i32, y: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:156:32 + --> tests/ui/needless_pass_by_ref_mut.rs:151:32 | LL | async fn a7(x: i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:160:24 + --> tests/ui/needless_pass_by_ref_mut.rs:155:24 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:160:45 + --> tests/ui/needless_pass_by_ref_mut.rs:155:45 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:194:16 + --> tests/ui/needless_pass_by_ref_mut.rs:189:16 | LL | fn cfg_warn(s: &mut u32) {} | ^^^^^^^^ help: consider changing to: `&u32` @@ -88,7 +88,7 @@ LL | fn cfg_warn(s: &mut u32) {} = note: this is cfg-gated and may require further changes error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:200:20 + --> tests/ui/needless_pass_by_ref_mut.rs:195:20 | LL | fn cfg_warn(s: &mut u32) {} | ^^^^^^^^ help: consider changing to: `&u32` @@ -96,19 +96,19 @@ LL | fn cfg_warn(s: &mut u32) {} = note: this is cfg-gated and may require further changes error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:214:39 + --> tests/ui/needless_pass_by_ref_mut.rs:209:39 | LL | async fn inner_async2(x: &mut i32, y: &mut u32) { | ^^^^^^^^ help: consider changing to: `&u32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:222:26 + --> tests/ui/needless_pass_by_ref_mut.rs:217:26 | LL | async fn inner_async3(x: &mut i32, y: &mut u32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:241:34 + --> tests/ui/needless_pass_by_ref_mut.rs:236:34 | LL | pub async fn call_in_closure1(n: &mut str) { | ^^^^^^^^ help: consider changing to: `&str` @@ -116,15 +116,7 @@ LL | pub async fn call_in_closure1(n: &mut str) { = warning: changing this function will impact semver compatibility error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:253:25 - | -LL | pub async fn closure(n: &mut usize) -> impl '_ + FnMut() { - | ^^^^^^^^^^ help: consider changing to: `&usize` - | - = warning: changing this function will impact semver compatibility - -error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:260:20 + --> tests/ui/needless_pass_by_ref_mut.rs:255:20 | LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize { | ^^^^^^^^^^ help: consider changing to: `&usize` @@ -132,7 +124,7 @@ LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize { = warning: changing this function will impact semver compatibility error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:271:26 + --> tests/ui/needless_pass_by_ref_mut.rs:266:26 | LL | pub async fn closure4(n: &mut usize) { | ^^^^^^^^^^ help: consider changing to: `&usize` @@ -140,64 +132,88 @@ LL | pub async fn closure4(n: &mut usize) { = warning: changing this function will impact semver compatibility error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:311:18 + --> tests/ui/needless_pass_by_ref_mut.rs:315:12 + | +LL | fn bar(&mut self) {} + | ^^^^^^^^^ help: consider changing to: `&self` + +error: this argument is a mutable reference, but not used mutably + --> tests/ui/needless_pass_by_ref_mut.rs:317:18 + | +LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { + | ^^^^^^^^^ help: consider changing to: `&self` + +error: this argument is a mutable reference, but not used mutably + --> tests/ui/needless_pass_by_ref_mut.rs:317:45 + | +LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { + | ^^^^^^^^ help: consider changing to: `&u32` + +error: this argument is a mutable reference, but not used mutably + --> tests/ui/needless_pass_by_ref_mut.rs:325:46 + | +LL | async fn foo2(&mut self, u: &mut i32, v: &mut u32) { + | ^^^^^^^^ help: consider changing to: `&u32` + +error: this argument is a mutable reference, but not used mutably + --> tests/ui/needless_pass_by_ref_mut.rs:341:18 | LL | fn _empty_tup(x: &mut (())) {} | ^^^^^^^^^ help: consider changing to: `&()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:312:19 + --> tests/ui/needless_pass_by_ref_mut.rs:342:19 | LL | fn _single_tup(x: &mut ((i32,))) {} | ^^^^^^^^^^^^^ help: consider changing to: `&(i32,)` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:313:18 + --> tests/ui/needless_pass_by_ref_mut.rs:343:18 | LL | fn _multi_tup(x: &mut ((i32, u32))) {} | ^^^^^^^^^^^^^^^^^ help: consider changing to: `&(i32, u32)` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:314:11 + --> tests/ui/needless_pass_by_ref_mut.rs:344:11 | LL | fn _fn(x: &mut (fn())) {} | ^^^^^^^^^^^ help: consider changing to: `&fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:316:23 + --> tests/ui/needless_pass_by_ref_mut.rs:346:23 | LL | fn _extern_rust_fn(x: &mut extern "Rust" fn()) {} | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "Rust" fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:317:20 + --> tests/ui/needless_pass_by_ref_mut.rs:347:20 | LL | fn _extern_c_fn(x: &mut extern "C" fn()) {} | ^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "C" fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:318:18 + --> tests/ui/needless_pass_by_ref_mut.rs:348:18 | LL | fn _unsafe_fn(x: &mut unsafe fn()) {} | ^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:319:25 + --> tests/ui/needless_pass_by_ref_mut.rs:349:25 | LL | fn _unsafe_extern_fn(x: &mut unsafe extern "C" fn()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:320:20 + --> tests/ui/needless_pass_by_ref_mut.rs:350:20 | LL | fn _fn_with_arg(x: &mut unsafe extern "C" fn(i32)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn(i32)` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:321:20 + --> tests/ui/needless_pass_by_ref_mut.rs:351:20 | LL | fn _fn_with_ret(x: &mut unsafe extern "C" fn() -> (i32)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn() -> (i32)` -error: aborting due to 31 previous errors +error: aborting due to 34 previous errors From adab7d08d75f8e92c1202aff3f0abd797da1062b Mon Sep 17 00:00:00 2001 From: J-ZhengLi Date: Fri, 19 Apr 2024 15:55:20 +0800 Subject: [PATCH 018/279] [`collection_is_never_read`]: check clousure in method args --- clippy_lints/src/collection_is_never_read.rs | 27 +++++++++++++++++--- tests/ui/collection_is_never_read.rs | 14 ++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/collection_is_never_read.rs b/clippy_lints/src/collection_is_never_read.rs index 6942ca536404..70856b808810 100644 --- a/clippy_lints/src/collection_is_never_read.rs +++ b/clippy_lints/src/collection_is_never_read.rs @@ -1,9 +1,9 @@ use clippy_utils::diagnostics::span_lint; use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item}; -use clippy_utils::visitors::for_each_expr_with_closures; +use clippy_utils::visitors::{for_each_expr_with_closures, Visitable}; use clippy_utils::{get_enclosing_block, path_to_local_id}; use core::ops::ControlFlow; -use rustc_hir::{Block, ExprKind, HirId, LangItem, LetStmt, Node, PatKind}; +use rustc_hir::{Body, ExprKind, HirId, LangItem, LetStmt, Node, PatKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; use rustc_span::symbol::sym; @@ -77,7 +77,7 @@ fn match_acceptable_type(cx: &LateContext<'_>, local: &LetStmt<'_>, collections: || is_type_lang_item(cx, ty, LangItem::String) } -fn has_no_read_access<'tcx>(cx: &LateContext<'tcx>, id: HirId, block: &'tcx Block<'tcx>) -> bool { +fn has_no_read_access<'tcx, T: Visitable<'tcx>>(cx: &LateContext<'tcx>, id: HirId, block: T) -> bool { let mut has_access = false; let mut has_read_access = false; @@ -109,11 +109,30 @@ fn has_no_read_access<'tcx>(cx: &LateContext<'tcx>, id: HirId, block: &'tcx Bloc // traits (identified as local, based on the orphan rule), pessimistically assume that they might // have side effects, so consider them a read. if let Node::Expr(parent) = cx.tcx.parent_hir_node(expr.hir_id) - && let ExprKind::MethodCall(_, receiver, _, _) = parent.kind + && let ExprKind::MethodCall(_, receiver, args, _) = parent.kind && path_to_local_id(receiver, id) && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id) && !method_def_id.is_local() { + // If this "official" method takes closures, + // it has read access if one of the closures has read access. + // + // items.retain(|item| send_item(item).is_ok()); + let is_read_in_closure_arg = args.iter().any(|arg| { + if let ExprKind::Closure(closure) = arg.kind + // To keep things simple, we only check the first param to see if its read. + && let Body { params: [param, ..], value } = cx.tcx.hir().body(closure.body) + { + !has_no_read_access(cx, param.hir_id, *value) + } else { + false + } + }); + if is_read_in_closure_arg { + has_read_access = true; + return ControlFlow::Break(()); + } + // The method call is a statement, so the return value is not used. That's not a read access: // // id.foo(args); diff --git a/tests/ui/collection_is_never_read.rs b/tests/ui/collection_is_never_read.rs index bd281f7870ce..eeb10da3402a 100644 --- a/tests/ui/collection_is_never_read.rs +++ b/tests/ui/collection_is_never_read.rs @@ -222,3 +222,17 @@ fn supported_types() { //~^ ERROR: collection is never read x.push_front(1); } + +fn issue11783() { + struct Sender; + impl Sender { + fn send(&self, msg: String) -> Result<(), ()> { + // pretend to send message + println!("{msg}"); + Ok(()) + } + } + + let mut users: Vec = vec![]; + users.retain(|user| user.send("hello".to_string()).is_ok()); +} From 206b1a1ac9df38ca5278a6db9954f9c62bd34b17 Mon Sep 17 00:00:00 2001 From: Quinn Sinclair Date: Wed, 17 Apr 2024 13:25:39 +0300 Subject: [PATCH 019/279] Threadlocal_initializer_can_be_made_const will not trigger for unreachable initializers This commit introduces a check to ensure that the lint won't trigger when the initializer is unreachable, such as: ``` thread_local! { static STATE: Cell = panic!(); } ``` This is achieved by looking at the unpeeled initializer expression and ensuring that the parent macro is not `panic!()`, `todo!()`, `unreachable!()`, `unimplemented!()`. fixes #12637 changelog: [`threadlocal_initializer_can_be_made_const`] will no longer trigger on `unreachable` macros. --- ...ead_local_initializer_can_be_made_const.rs | 36 ++++++++++++++++--- ..._local_initializer_can_be_made_const.fixed | 33 ++++++++++++++++- ...ead_local_initializer_can_be_made_const.rs | 33 ++++++++++++++++- 3 files changed, 95 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/thread_local_initializer_can_be_made_const.rs b/clippy_lints/src/thread_local_initializer_can_be_made_const.rs index c1e24674e3e8..4af3ee74d0ea 100644 --- a/clippy_lints/src/thread_local_initializer_can_be_made_const.rs +++ b/clippy_lints/src/thread_local_initializer_can_be_made_const.rs @@ -1,13 +1,14 @@ use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::macros::macro_backtrace; use clippy_utils::qualify_min_const_fn::is_min_const_fn; use clippy_utils::source::snippet; use clippy_utils::{fn_has_unsatisfiable_preds, peel_blocks}; use rustc_errors::Applicability; -use rustc_hir::{intravisit, ExprKind}; +use rustc_hir::{intravisit, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; -use rustc_span::sym::thread_local_macro; +use rustc_span::sym::{self, thread_local_macro}; declare_clippy_lint! { /// ### What it does @@ -69,6 +70,26 @@ fn is_thread_local_initializer( ) } +fn is_unreachable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + if let Some(macro_call) = macro_backtrace(expr.span).next() + && let Some(diag_name) = cx.tcx.get_diagnostic_name(macro_call.def_id) + { + return (matches!( + diag_name, + sym::core_panic_macro + | sym::std_panic_macro + | sym::core_panic_2015_macro + | sym::std_panic_2015_macro + | sym::core_panic_2021_macro + ) && !cx.tcx.hir().is_inside_const_context(expr.hir_id)) + || matches!( + diag_name, + sym::unimplemented_macro | sym::todo_macro | sym::unreachable_macro | sym::unreachable_2015_macro + ); + } + false +} + #[inline] fn initializer_can_be_made_const(cx: &LateContext<'_>, defid: rustc_span::def_id::DefId, msrv: &Msrv) -> bool { // Building MIR for `fn`s with unsatisfiable preds results in ICE. @@ -102,12 +123,17 @@ impl<'tcx> LateLintPass<'tcx> for ThreadLocalInitializerCanBeMadeConst { // for details on this issue, see: // https://github.com/rust-lang/rust-clippy/pull/12276 && !cx.tcx.is_const_fn(defid) - && initializer_can_be_made_const(cx, defid, &self.msrv) - // we know that the function is const-qualifiable, so now - // we need only to get the initializer expression to span-lint it. && let ExprKind::Block(block, _) = body.value.kind && let Some(unpeeled) = block.expr && let ret_expr = peel_blocks(unpeeled) + // A common pattern around threadlocal! is to make the value unreachable + // to force an initialization before usage + // https://github.com/rust-lang/rust-clippy/issues/12637 + // we ensure that this is reachable before we check in mir + && !is_unreachable(cx, ret_expr) + && initializer_can_be_made_const(cx, defid, &self.msrv) + // we know that the function is const-qualifiable, so now + // we need only to get the initializer expression to span-lint it. && let initializer_snippet = snippet(cx, ret_expr.span, "thread_local! { ... }") && initializer_snippet != "thread_local! { ... }" { diff --git a/tests/ui/thread_local_initializer_can_be_made_const.fixed b/tests/ui/thread_local_initializer_can_be_made_const.fixed index a6ed59d49c54..4c9bd0bd8634 100644 --- a/tests/ui/thread_local_initializer_can_be_made_const.fixed +++ b/tests/ui/thread_local_initializer_can_be_made_const.fixed @@ -1,6 +1,6 @@ #![warn(clippy::thread_local_initializer_can_be_made_const)] -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; fn main() { // lint and suggest const @@ -36,6 +36,37 @@ fn main() { } } +fn issue_12637() { + /// The set methods on LocalKey> and LocalKey> are + /// guaranteed to bypass the thread_local's initialization expression. + /// See rust-lang/rust#92122. Thus, = panic!() is a useful idiom for + /// forcing the use of set on each thread before it accesses the thread local in any other + /// manner. + thread_local! { + static STATE_12637_PANIC: Cell = panic!(); + } + STATE_12637_PANIC.set(9); + println!("{}", STATE_12637_PANIC.get()); + + thread_local! { + static STATE_12637_TODO: Cell = todo!(); + } + STATE_12637_TODO.set(9); + println!("{}", STATE_12637_TODO.get()); + + thread_local! { + static STATE_12637_UNIMPLEMENTED: Cell = unimplemented!(); + } + STATE_12637_UNIMPLEMENTED.set(9); + println!("{}", STATE_12637_UNIMPLEMENTED.get()); + + thread_local! { + static STATE_12637_UNREACHABLE: Cell = unreachable!(); + } + STATE_12637_UNREACHABLE.set(9); + println!("{}", STATE_12637_UNREACHABLE.get()); +} + #[clippy::msrv = "1.58"] fn f() { thread_local! { diff --git a/tests/ui/thread_local_initializer_can_be_made_const.rs b/tests/ui/thread_local_initializer_can_be_made_const.rs index 3f0159c58065..eb336f0dd191 100644 --- a/tests/ui/thread_local_initializer_can_be_made_const.rs +++ b/tests/ui/thread_local_initializer_can_be_made_const.rs @@ -1,6 +1,6 @@ #![warn(clippy::thread_local_initializer_can_be_made_const)] -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; fn main() { // lint and suggest const @@ -36,6 +36,37 @@ fn main() { } } +fn issue_12637() { + /// The set methods on LocalKey> and LocalKey> are + /// guaranteed to bypass the thread_local's initialization expression. + /// See rust-lang/rust#92122. Thus, = panic!() is a useful idiom for + /// forcing the use of set on each thread before it accesses the thread local in any other + /// manner. + thread_local! { + static STATE_12637_PANIC: Cell = panic!(); + } + STATE_12637_PANIC.set(9); + println!("{}", STATE_12637_PANIC.get()); + + thread_local! { + static STATE_12637_TODO: Cell = todo!(); + } + STATE_12637_TODO.set(9); + println!("{}", STATE_12637_TODO.get()); + + thread_local! { + static STATE_12637_UNIMPLEMENTED: Cell = unimplemented!(); + } + STATE_12637_UNIMPLEMENTED.set(9); + println!("{}", STATE_12637_UNIMPLEMENTED.get()); + + thread_local! { + static STATE_12637_UNREACHABLE: Cell = unreachable!(); + } + STATE_12637_UNREACHABLE.set(9); + println!("{}", STATE_12637_UNREACHABLE.get()); +} + #[clippy::msrv = "1.58"] fn f() { thread_local! { From 17073464ad9746995a733f87cf25b6d6eb3d9f35 Mon Sep 17 00:00:00 2001 From: beepster4096 <19316085+beepster4096@users.noreply.github.com> Date: Fri, 19 Apr 2024 16:50:46 -0700 Subject: [PATCH 020/279] remove optionality from MoveData::base_local --- compiler/rustc_borrowck/src/borrow_set.rs | 4 +--- compiler/rustc_mir_dataflow/src/move_paths/mod.rs | 15 +++++---------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrow_set.rs b/compiler/rustc_borrowck/src/borrow_set.rs index a38dd286be51..ae6ac23c0f53 100644 --- a/compiler/rustc_borrowck/src/borrow_set.rs +++ b/compiler/rustc_borrowck/src/borrow_set.rs @@ -108,9 +108,7 @@ impl LocalsStateAtExit { has_storage_dead.visit_body(body); let mut has_storage_dead_or_moved = has_storage_dead.0; for move_out in &move_data.moves { - if let Some(index) = move_data.base_local(move_out.path) { - has_storage_dead_or_moved.insert(index); - } + has_storage_dead_or_moved.insert(move_data.base_local(move_out.path)); } LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs index 22cf3999239c..830f44df5fb3 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs @@ -358,20 +358,15 @@ impl<'tcx> MoveData<'tcx> { builder::gather_moves(body, tcx, param_env, filter) } - /// For the move path `mpi`, returns the root local variable (if any) that starts the path. - /// (e.g., for a path like `a.b.c` returns `Some(a)`) - pub fn base_local(&self, mut mpi: MovePathIndex) -> Option { + /// For the move path `mpi`, returns the root local variable that starts the path. + /// (e.g., for a path like `a.b.c` returns `a`) + pub fn base_local(&self, mut mpi: MovePathIndex) -> Local { loop { let path = &self.move_paths[mpi]; if let Some(l) = path.place.as_local() { - return Some(l); - } - if let Some(parent) = path.parent { - mpi = parent; - continue; - } else { - return None; + return l; } + mpi = path.parent.expect("root move paths should be locals"); } } From 898baf81cdaf1682c6cbf6e575fb546741bc73a0 Mon Sep 17 00:00:00 2001 From: Samuel Moelius Date: Sat, 20 Apr 2024 01:16:30 +0000 Subject: [PATCH 021/279] Add `test_with_disallowed_name` --- tests/ui/disallowed_names.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/ui/disallowed_names.rs b/tests/ui/disallowed_names.rs index 9a701a2cbcfb..13c883409bf6 100644 --- a/tests/ui/disallowed_names.rs +++ b/tests/ui/disallowed_names.rs @@ -71,3 +71,8 @@ mod tests { } } } + +#[test] +fn test_with_disallowed_name() { + let foo = 0; +} From de258cc6becde010381502ae0e80b4aca4064e3c Mon Sep 17 00:00:00 2001 From: Samuel Moelius Date: Sat, 20 Apr 2024 01:17:28 +0000 Subject: [PATCH 022/279] Fix `is_test_module_or_function` --- clippy_utils/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index a13885b022f6..5ea9b375f5b9 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -2505,8 +2505,9 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym /// Note: Add `//@compile-flags: --test` to UI tests with a `#[test]` function pub fn is_in_test_function(tcx: TyCtxt<'_>, id: HirId) -> bool { with_test_item_names(tcx, tcx.parent_module(id), |names| { - tcx.hir() - .parent_iter(id) + let node = tcx.hir_node(id); + once((id, node)) + .chain(tcx.hir().parent_iter(id)) // Since you can nest functions we need to collect all until we leave // function scope .any(|(_id, node)| { From 38ded129236f112a7421f311aeb8ca750b661443 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Thu, 18 Apr 2024 20:03:45 +0200 Subject: [PATCH 023/279] Abort a process when FD ownership is violated When an EBADF happens then something else already touched an FD in ways it is not allowed to. At that point things can already be arbitrarily bad, e.g. clobbered mmaps. Recovery is not possible. All we can do is hasten the fire. --- library/std/src/os/fd/owned.rs | 15 ++++++++++++++- library/std/src/sys/pal/unix/fs.rs | 21 +++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 010ce4e5076b..8c421540af40 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -176,7 +176,20 @@ impl Drop for OwnedFd { // something like EINTR), we might close another valid file descriptor // opened after we closed ours. #[cfg(not(target_os = "hermit"))] - let _ = libc::close(self.fd); + { + use crate::sys::os::errno; + // ideally this would use assert_unsafe_precondition!, but that's only in core + if cfg!(debug_assertions) { + // close() can bubble up error codes from FUSE which can send semantically + // inappropriate error codes including EBADF. + // So we check file flags instead which live on the file descriptor and not the underlying file. + // The downside is that it costs an extra syscall, so we only do it for debug. + if libc::fcntl(self.fd, libc::F_GETFD) == -1 && errno() == libc::EBADF { + rtabort!("IO Safety violation: owned file descriptor already closed"); + } + } + let _ = libc::close(self.fd); + } #[cfg(target_os = "hermit")] let _ = hermit_abi::close(self.fd); } diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 3456155509ef..2d57a9d81c91 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -870,6 +870,27 @@ impl Iterator for ReadDir { impl Drop for Dir { fn drop(&mut self) { + // ideally this would use assert_unsafe_precondition!, but that's only in core + #[cfg(all( + debug_assertions, + not(any( + target_os = "redox", + target_os = "nto", + target_os = "vita", + target_os = "hurd", + )) + ))] + { + use crate::sys::os::errno; + // close() can bubble up error codes from FUSE which can send semantically + // inappropriate error codes including EBADF. + // So we check file flags instead which live on the file descriptor and not the underlying file. + // The downside is that it costs an extra syscall, so we only do it for debug. + let fd = unsafe { libc::dirfd(self.0) }; + if unsafe { libc::fcntl(fd, libc::F_GETFD) } == -1 && errno() == libc::EBADF { + rtabort!("IO Safety violation: DIR*'s owned file descriptor already closed"); + } + } let r = unsafe { libc::closedir(self.0) }; assert!( r == 0 || crate::io::Error::last_os_error().is_interrupted(), From 8088ea0ba026127786b23c516d1371d5e06eef30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Fri, 19 Apr 2024 18:02:21 +0200 Subject: [PATCH 024/279] add test for incremental ICE: slice-pattern-const.rs #83085 Fixes #83085 --- .../slice-pattern-const-ice-83085.rs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tests/incremental/slice-pattern-const-ice-83085.rs diff --git a/tests/incremental/slice-pattern-const-ice-83085.rs b/tests/incremental/slice-pattern-const-ice-83085.rs new file mode 100644 index 000000000000..4d318fd7ec18 --- /dev/null +++ b/tests/incremental/slice-pattern-const-ice-83085.rs @@ -0,0 +1,39 @@ +//@ compile-flags: -Zincremental-verify-ich=yes +// issue: rust-lang/rust#83085 incremental ICE: forcing query with already existing `DepNode` +// this used to fail to build straight away without needing any kind of +// stage1/2 builds but tidy demands it +//@ revisions:rpass1 rpass2 + +fn main() { + const BOO: &[u8; 0] = &[]; + match &[] { + BOO => (), + b"" => (), + _ => (), + } +} + +#[derive(PartialEq, Eq)] +struct Id<'a> { + ns: &'a str, +} +fn visit_struct() { + let id = Id { ns: "random1" }; + const FLAG: Id<'static> = Id { + ns: "needs_to_be_the_same", + }; + match id { + FLAG => {} + _ => {} + } +} +fn visit_struct2() { + let id = Id { ns: "random2" }; + const FLAG: Id<'static> = Id { + ns: "needs_to_be_the_same", + }; + match id { + FLAG => {} + _ => {} + } +} From a2fa934927a3d39860572f722bbe5f3cb691cf19 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 21 Apr 2024 13:21:36 -0700 Subject: [PATCH 025/279] bootstrap: Describe build_steps::test for 2024 The description was most accurate when it was still called rustbuild, and I presume indeed did mostly run in CI. It has become something more so try to describe it better for current-day usage. --- src/bootstrap/src/core/build_steps/test.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 1980980b6d05..867b359ccb13 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1,7 +1,7 @@ -//! Implementation of the test-related targets of the build system. +//! Build-and-run steps for `./x.py test` test fixtures //! -//! This file implements the various regression test suites that we execute on -//! our CI. +//! `./x.py test` (aka [`Kind::Test`]) is currently allowed to reach build steps in other modules. +//! However, this contains ~all test parts we expect people to be able to build and run locally. use std::env; use std::ffi::OsStr; From 2042616134048f5226a97e405cb8357cde355e36 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 21 Apr 2024 13:32:46 -0700 Subject: [PATCH 026/279] bootstrap: Describe build_steps::run --- src/bootstrap/src/core/build_steps/run.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 7028bffea544..0a428ec5ca0a 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -1,3 +1,8 @@ +//! Build-and-run steps for in-repo tools +//! +//! A bit of a hodge-podge as e.g. if a tool's a test fixture it should be in `build_steps::test`. +//! If it can be reached from `./x.py run` it can go here. + use std::path::PathBuf; use std::process::Command; From 35ed725cd2c586b0aa5ebf3d2182c69e1cb0e392 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 21 Apr 2024 13:31:41 -0700 Subject: [PATCH 027/279] bootstrap: Describe build_steps::toolstate --- src/bootstrap/src/core/build_steps/toolstate.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/toolstate.rs b/src/bootstrap/src/core/build_steps/toolstate.rs index deb782cad0ce..6065aa1414fe 100644 --- a/src/bootstrap/src/core/build_steps/toolstate.rs +++ b/src/bootstrap/src/core/build_steps/toolstate.rs @@ -1,3 +1,7 @@ +//! Toolstate checks to keep tools building +//! +//! Reachable via `./x.py test` but mostly relevant for CI, since it isn't run locally by default. + use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::utils::helpers::t; use serde_derive::{Deserialize, Serialize}; From 8c40d0efa7881d49895398c8536c212c1e9e93cf Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 21 Apr 2024 13:39:11 -0700 Subject: [PATCH 028/279] bootstrap: Describe build_steps::suggest --- src/bootstrap/src/core/build_steps/suggest.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/suggest.rs b/src/bootstrap/src/core/build_steps/suggest.rs index c057fa9a5667..754d1e61da8c 100644 --- a/src/bootstrap/src/core/build_steps/suggest.rs +++ b/src/bootstrap/src/core/build_steps/suggest.rs @@ -1,3 +1,5 @@ +//! Attempt to magically identify good tests to run + #![cfg_attr(feature = "build-metrics", allow(unused))] use clap::Parser; From bc37f9e2040235a4e6b8bed6c6db4f064fea15cc Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 21 Apr 2024 13:32:59 -0700 Subject: [PATCH 029/279] bootstrap: Describe build_steps::setup --- src/bootstrap/src/core/build_steps/setup.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 7bc68b5aec11..6b2b7e5dcaca 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -1,3 +1,9 @@ +//! First time setup of a dev environment +//! +//! These are build-and-run steps for `./x.py setup`, which allows quickly setting up the directory +//! for modifying, building, and running the compiler and library. The main convenience is to allow +//! not having to painstakingly set every single option in config.toml. + use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::t; use crate::utils::change_tracker::CONFIG_CHANGE_HISTORY; From ce27ea935edd4cc04455e6abfdc8ba8ed86be451 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 21 Apr 2024 13:52:42 -0700 Subject: [PATCH 030/279] bootstrap: Demagic a repeating path --- src/bootstrap/src/core/build_steps/setup.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 6b2b7e5dcaca..a01d20e8c21a 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -31,6 +31,8 @@ pub enum Profile { None, } +static PROFILE_DIR: &str = "src/bootstrap/defaults"; + /// A list of historical hashes of `src/etc/rust_analyzer_settings.json`. /// New entries should be appended whenever this is updated so we can detect /// outdated vs. user-modified settings files. @@ -47,7 +49,7 @@ static RUST_ANALYZER_SETTINGS: &str = include_str!("../../../../etc/rust_analyze impl Profile { fn include_path(&self, src_path: &Path) -> PathBuf { - PathBuf::from(format!("{}/src/bootstrap/defaults/config.{}.toml", src_path.display(), self)) + PathBuf::from(format!("{}/{PROFILE_DIR}/config.{}.toml", src_path.display(), self)) } pub fn all() -> impl Iterator { @@ -227,7 +229,7 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) { let latest_change_id = CONFIG_CHANGE_HISTORY.last().unwrap().change_id; let settings = format!( - "# Includes one of the default files in src/bootstrap/defaults\n\ + "# Includes one of the default files in {PROFILE_DIR}\n\ profile = \"{profile}\"\n\ change-id = {latest_change_id}\n" ); From b756b11ae399413ec728e3a01393a4eba00be2fc Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 21 Apr 2024 18:39:48 -0700 Subject: [PATCH 031/279] bootstrap: Describe build_steps::clean how 2024 knows it --- src/bootstrap/src/core/build_steps/clean.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/clean.rs b/src/bootstrap/src/core/build_steps/clean.rs index 9e103a350e65..10303f6af9e1 100644 --- a/src/bootstrap/src/core/build_steps/clean.rs +++ b/src/bootstrap/src/core/build_steps/clean.rs @@ -1,4 +1,4 @@ -//! Implementation of `make clean` in rustbuild. +//! `./x.py clean` //! //! Responsible for cleaning out a build directory of all old and stale //! artifacts to prepare for a fresh build. Currently doesn't remove the From 35d14dd96b7847e4fccefea08467efb90ce0e67e Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Mon, 22 Apr 2024 16:44:14 +0300 Subject: [PATCH 032/279] drop deprecated value `if-available` for `download-ci-llvm` option It's been 5 months since we deprecated this. It should be fine to drop its support now. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/config/config.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 2acce6273598..2c85f6b92aaf 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -2488,11 +2488,6 @@ impl Config { b } - // FIXME: "if-available" is deprecated. Remove this block later (around mid 2024) - // to not break builds between the recent-to-old checkouts. - Some(StringOrBool::String(s)) if s == "if-available" => { - llvm::is_ci_llvm_available(self, asserts) - } Some(StringOrBool::String(s)) if s == "if-unchanged" => if_unchanged(), Some(StringOrBool::String(other)) => { panic!("unrecognized option for download-ci-llvm: {:?}", other) From 67e3668c9a6db4ff33371b6c6daec34b7323d638 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 14 Apr 2024 23:07:00 +0300 Subject: [PATCH 033/279] introduce `x vendor` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/mod.rs | 1 + src/bootstrap/src/core/build_steps/vendor.rs | 61 ++++++++++ src/bootstrap/src/core/builder.rs | 9 +- src/bootstrap/src/core/config/config.rs | 6 +- src/bootstrap/src/core/config/flags.rs | 24 ++++ src/etc/completions/x.py.fish | 37 ++++++ src/etc/completions/x.py.ps1 | 44 +++++++ src/etc/completions/x.py.sh | 119 ++++++++++++++++++- src/etc/completions/x.py.zsh | 51 ++++++++ 9 files changed, 347 insertions(+), 5 deletions(-) create mode 100644 src/bootstrap/src/core/build_steps/vendor.rs diff --git a/src/bootstrap/src/core/build_steps/mod.rs b/src/bootstrap/src/core/build_steps/mod.rs index 9b7378165de4..381ee7ef53b4 100644 --- a/src/bootstrap/src/core/build_steps/mod.rs +++ b/src/bootstrap/src/core/build_steps/mod.rs @@ -14,3 +14,4 @@ pub(crate) mod synthetic_targets; pub(crate) mod test; pub(crate) mod tool; pub(crate) mod toolstate; +pub(crate) mod vendor; diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs new file mode 100644 index 000000000000..68f1b1bef3f3 --- /dev/null +++ b/src/bootstrap/src/core/build_steps/vendor.rs @@ -0,0 +1,61 @@ +use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; +use std::path::PathBuf; +use std::process::Command; + +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub(crate) struct Vendor { + sync_args: Vec, + versioned_dirs: bool, + root_dir: PathBuf, +} + +impl Step for Vendor { + type Output = (); + const DEFAULT: bool = true; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("placeholder").default_condition(true) + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(Vendor { + sync_args: run.builder.config.cmd.vendor_sync_args(), + versioned_dirs: run.builder.config.cmd.vendor_versioned_dirs(), + root_dir: run.builder.src.clone(), + }); + } + + fn run(self, builder: &Builder<'_>) -> Self::Output { + let mut cmd = Command::new(&builder.initial_cargo); + cmd.arg("vendor"); + + if self.versioned_dirs { + cmd.arg("--versioned-dirs"); + } + + // Sync these paths by default. + for p in [ + "src/tools/cargo/Cargo.toml", + "src/tools/rust-analyzer/Cargo.toml", + "compiler/rustc_codegen_cranelift/Cargo.toml", + "compiler/rustc_codegen_gcc/Cargo.toml", + "src/bootstrap/Cargo.toml", + ] { + cmd.arg("--sync").arg(builder.src.join(p)); + } + + // Also sync explicitly requested paths. + for sync_arg in self.sync_args { + cmd.arg("--sync").arg(sync_arg); + } + + // Will read the libstd Cargo.toml + // which uses the unstable `public-dependency` feature. + cmd.env("RUSTC_BOOTSTRAP", "1"); + + cmd.current_dir(self.root_dir); + + builder.run(&mut cmd); + } +} diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index adef9ebd0e30..09183d599fc1 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -14,8 +14,9 @@ use std::sync::OnceLock; use std::time::{Duration, Instant}; use crate::core::build_steps::tool::{self, SourceType}; -use crate::core::build_steps::{check, clean, compile, dist, doc, install, run, setup, test}; -use crate::core::build_steps::{clippy, llvm}; +use crate::core::build_steps::{ + check, clean, clippy, compile, dist, doc, install, llvm, run, setup, test, vendor, +}; use crate::core::config::flags::{Color, Subcommand}; use crate::core::config::{DryRun, SplitDebuginfo, TargetSelection}; use crate::prepare_behaviour_dump_dir; @@ -638,6 +639,7 @@ pub enum Kind { Run, Setup, Suggest, + Vendor, } impl Kind { @@ -658,6 +660,7 @@ impl Kind { Kind::Run => "run", Kind::Setup => "setup", Kind::Suggest => "suggest", + Kind::Vendor => "vendor", } } @@ -920,6 +923,7 @@ impl<'a> Builder<'a> { ), Kind::Setup => describe!(setup::Profile, setup::Hook, setup::Link, setup::Vscode), Kind::Clean => describe!(clean::CleanAll, clean::Rustc, clean::Std), + Kind::Vendor => describe!(vendor::Vendor), // special-cased in Build::build() Kind::Format | Kind::Suggest => vec![], } @@ -992,6 +996,7 @@ impl<'a> Builder<'a> { Kind::Setup, path.as_ref().map_or([].as_slice(), |path| std::slice::from_ref(path)), ), + Subcommand::Vendor { .. } => (Kind::Vendor, &paths[..]), }; Self::new_internal(build, kind, paths.to_owned()) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 2acce6273598..687c80678185 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -2027,7 +2027,8 @@ impl Config { | Subcommand::Run { .. } | Subcommand::Setup { .. } | Subcommand::Format { .. } - | Subcommand::Suggest { .. } => flags.stage.unwrap_or(0), + | Subcommand::Suggest { .. } + | Subcommand::Vendor { .. } => flags.stage.unwrap_or(0), }; // CI should always run stage 2 builds, unless it specifically states otherwise @@ -2054,7 +2055,8 @@ impl Config { | Subcommand::Run { .. } | Subcommand::Setup { .. } | Subcommand::Format { .. } - | Subcommand::Suggest { .. } => {} + | Subcommand::Suggest { .. } + | Subcommand::Vendor { .. } => {} } } diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index aaa2a2c47e07..e3cc992bb5de 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -456,6 +456,15 @@ Arguments: #[arg(long)] run: bool, }, + /// Vendor dependencies + Vendor { + /// Additional `Cargo.toml` to sync and vendor + #[arg(long)] + sync: Vec, + /// Always include version in subdir name + #[arg(long)] + versioned_dirs: bool, + }, } impl Subcommand { @@ -476,6 +485,7 @@ impl Subcommand { Subcommand::Run { .. } => Kind::Run, Subcommand::Setup { .. } => Kind::Setup, Subcommand::Suggest { .. } => Kind::Suggest, + Subcommand::Vendor { .. } => Kind::Vendor, } } @@ -581,6 +591,20 @@ impl Subcommand { _ => false, } } + + pub fn vendor_versioned_dirs(&self) -> bool { + match *self { + Subcommand::Vendor { versioned_dirs, .. } => versioned_dirs, + _ => false, + } + } + + pub fn vendor_sync_args(&self) -> Vec { + match self { + Subcommand::Vendor { sync, .. } => sync.clone(), + _ => vec![], + } + } } /// Returns the shell completion for a given shell, if the result differs from the current diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index 5ae27bc8c91c..40a25f13fcbd 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -47,6 +47,7 @@ complete -c x.py -n "__fish_use_subcommand" -f -a "install" -d 'Install distribu complete -c x.py -n "__fish_use_subcommand" -f -a "run" -d 'Run tools contained in this repository' complete -c x.py -n "__fish_use_subcommand" -f -a "setup" -d 'Set up the environment for development' complete -c x.py -n "__fish_use_subcommand" -f -a "suggest" -d 'Suggest a subset of tests to run, based on modified files' +complete -c x.py -n "__fish_use_subcommand" -f -a "vendor" -d 'Vendor dependencies' complete -c x.py -n "__fish_seen_subcommand_from build" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_seen_subcommand_from build" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from build" -l build -d 'build target of the stage0 compiler' -r -f @@ -590,3 +591,39 @@ complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-profile-genera complete -c x.py -n "__fish_seen_subcommand_from suggest" -l enable-bolt-settings -d 'Enable BOLT link flags' complete -c x.py -n "__fish_seen_subcommand_from suggest" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x.py -n "__fish_seen_subcommand_from suggest" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l sync -d 'Additional `Cargo.toml` to sync and vendor' -r -F +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l skip -d 'build paths to skip' -r -F +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l rustc-error-format -r -f +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from vendor" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}" +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}" +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}" +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l versioned-dirs -d 'Always include version in subdir name' +complete -c x.py -n "__fish_seen_subcommand_from vendor" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_seen_subcommand_from vendor" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims' +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)' +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l enable-bolt-settings -d 'Enable BOLT link flags' +complete -c x.py -n "__fish_seen_subcommand_from vendor" -l skip-stage0-validation -d 'Skip stage0 compiler validation' +complete -c x.py -n "__fish_seen_subcommand_from vendor" -s h -l help -d 'Print help (see more with \'--help\')' diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index d39639a1f91d..f3d1d372c733 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -74,6 +74,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('run', 'run', [CompletionResultType]::ParameterValue, 'Run tools contained in this repository') [CompletionResult]::new('setup', 'setup', [CompletionResultType]::ParameterValue, 'Set up the environment for development') [CompletionResult]::new('suggest', 'suggest', [CompletionResultType]::ParameterValue, 'Suggest a subset of tests to run, based on modified files') + [CompletionResult]::new('vendor', 'vendor', [CompletionResultType]::ParameterValue, 'Vendor dependencies') break } 'x.py;build' { @@ -724,6 +725,49 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } + 'x.py;vendor' { + [CompletionResult]::new('--sync', 'sync', [CompletionResultType]::ParameterName, 'Additional `Cargo.toml` to sync and vendor') + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--reproducible-artifact', 'reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') + [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--versioned-dirs', 'versioned-dirs', [CompletionResultType]::ParameterName, 'Always include version in subdir name') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--dump-bootstrap-shims', 'dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--bypass-bootstrap-lock', 'bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags') + [CompletionResult]::new('--skip-stage0-validation', 'skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + break + } }) $completions.Where{ $_.CompletionText -like "$wordToComplete*" } | diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh index 1f1a9a70767f..82cacb52ffee 100644 --- a/src/etc/completions/x.py.sh +++ b/src/etc/completions/x.py.sh @@ -57,6 +57,9 @@ _x.py() { bootstrap,test) cmd="bootstrap__test" ;; + bootstrap,vendor) + cmd="bootstrap__vendor" + ;; *) ;; esac @@ -64,7 +67,7 @@ _x.py() { case "${cmd}" in x.py) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest" + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1879,6 +1882,120 @@ _x.py() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + x.py__vendor) + opts="-v -i -j -h --sync --versioned-dirs --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --sync) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --reproducible-artifact) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --set) + COMPREPLY=("${cur}") + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; esac } diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh index b920309ac2c1..12e96dbd40a3 100644 --- a/src/etc/completions/x.py.zsh +++ b/src/etc/completions/x.py.zsh @@ -742,6 +742,51 @@ _arguments "${_arguments_options[@]}" \ '--help[Print help (see more with '\''--help'\'')]' \ '*::paths -- paths for the subcommand:_files' \ && ret=0 +;; +(vendor) +_arguments "${_arguments_options[@]}" \ +'*--sync=[Additional \`Cargo.toml\` to sync and vendor]:SYNC:_files' \ +'--config=[TOML configuration file for build]:FILE:_files' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build=[build target of the stage0 compiler]:BUILD:( )' \ +'--host=[host targets to build]:HOST:( )' \ +'--target=[target targets to build]:TARGET:( )' \ +'*--exclude=[build paths to exclude]:PATH:_files' \ +'*--skip=[build paths to skip]:PATH:_files' \ +'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \ +'--on-fail=[command to run on failure]:CMD:_cmdstring' \ +'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \ +'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \ +'--src=[path to the root of the rust checkout]:DIR:_files -/' \ +'-j+[number of jobs to run in parallel]:JOBS:( )' \ +'--jobs=[number of jobs to run in parallel]:JOBS:( )' \ +'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \ +'--error-format=[rustc error format]:FORMAT:( )' \ +'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \ +'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \ +'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \ +'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ +'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ +'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \ +'*--set=[override options in config.toml]:section.option=value:( )' \ +'--versioned-dirs[Always include version in subdir name]' \ +'*-v[use verbose output (-vv for very verbose)]' \ +'*--verbose[use verbose output (-vv for very verbose)]' \ +'-i[use incremental compilation]' \ +'--incremental[use incremental compilation]' \ +'--include-default-paths[include default paths in addition to the provided ones]' \ +'--dry-run[dry run; don'\''t build anything]' \ +'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \ +'--json-output[use message-format=json]' \ +'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \ +'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \ +'--enable-bolt-settings[Enable BOLT link flags]' \ +'--skip-stage0-validation[Skip stage0 compiler validation]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +'*::paths -- paths for the subcommand:_files' \ +&& ret=0 ;; esac ;; @@ -766,6 +811,7 @@ _x.py_commands() { 'run:Run tools contained in this repository' \ 'setup:Set up the environment for development' \ 'suggest:Suggest a subset of tests to run, based on modified files' \ +'vendor:Vendor dependencies' \ ) _describe -t commands 'x.py commands' commands "$@" } @@ -844,6 +890,11 @@ _x.py__test_commands() { local commands; commands=() _describe -t commands 'x.py test commands' commands "$@" } +(( $+functions[_x.py__vendor_commands] )) || +_x.py__vendor_commands() { + local commands; commands=() + _describe -t commands 'x.py vendor commands' commands "$@" +} if [ "$funcstack[1]" = "_x.py" ]; then _x.py "$@" From 6dd011de64c2d6299a1dc3aa16d44d1b23ac2bae Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 14 Apr 2024 23:08:19 +0300 Subject: [PATCH 034/279] suggest `x.py vendor` instead of `cargo vendor` Signed-off-by: onur-ozkan --- src/bootstrap/bootstrap.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 39add60e705f..e464e444fea2 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -1035,14 +1035,8 @@ class RustBuild(object): if self.use_vendored_sources: vendor_dir = os.path.join(self.rust_root, 'vendor') if not os.path.exists(vendor_dir): - sync_dirs = "--sync ./src/tools/cargo/Cargo.toml " \ - "--sync ./src/tools/rust-analyzer/Cargo.toml " \ - "--sync ./compiler/rustc_codegen_cranelift/Cargo.toml " \ - "--sync ./compiler/rustc_codegen_gcc/Cargo.toml " \ - "--sync ./src/bootstrap/Cargo.toml " eprint('ERROR: vendoring required, but vendor directory does not exist.') - eprint(' Run `cargo vendor {}` to initialize the ' - 'vendor directory.'.format(sync_dirs)) + eprint(' Run `x.py vendor` to initialize the vendor directory.') eprint(' Alternatively, use the pre-vendored `rustc-src` dist component.') eprint(' To get a stable/beta/nightly version, download it from: ') eprint(' ' From 25babe9a79a2c5d35211e0d6bad348637ef2a246 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sun, 21 Apr 2024 16:34:42 +0200 Subject: [PATCH 035/279] export assert_unsafe_precondition macro for std-internal use --- library/core/src/intrinsics.rs | 2 +- library/core/src/lib.rs | 4 +++- library/core/src/ub_checks.rs | 8 ++++++-- library/std/src/lib.rs | 1 + 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 9406efd7ab24..7d2b84b98646 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2720,7 +2720,7 @@ pub const unsafe fn typed_swap(x: *mut T, y: *mut T) { #[unstable(feature = "core_intrinsics", issue = "none")] #[inline(always)] #[cfg_attr(not(bootstrap), rustc_intrinsic)] // just make it a regular fn in bootstrap -pub(crate) const fn ub_checks() -> bool { +pub const fn ub_checks() -> bool { cfg!(debug_assertions) } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 154565b6fee1..a7dcc4992f50 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -193,6 +193,7 @@ #![feature(str_split_inclusive_remainder)] #![feature(str_split_remainder)] #![feature(strict_provenance)] +#![feature(ub_checks)] #![feature(unchecked_shifts)] #![feature(utf16_extra)] #![feature(utf16_extra_const)] @@ -370,7 +371,8 @@ pub mod hint; pub mod intrinsics; pub mod mem; pub mod ptr; -mod ub_checks; +#[unstable(feature = "ub_checks", issue = "none")] +pub mod ub_checks; /* Core language traits */ diff --git a/library/core/src/ub_checks.rs b/library/core/src/ub_checks.rs index ff6b2d305395..1aa6a288e708 100644 --- a/library/core/src/ub_checks.rs +++ b/library/core/src/ub_checks.rs @@ -46,6 +46,8 @@ use crate::intrinsics::{self, const_eval_select}; /// variables cannot be optimized out in MIR, an innocent-looking `let` can produce enough /// debuginfo to have a measurable compile-time impact on debug builds. #[allow_internal_unstable(const_ub_checks)] // permit this to be called in stably-const fn +#[macro_export] +#[unstable(feature = "ub_checks", issue = "none")] macro_rules! assert_unsafe_precondition { ($kind:ident, $message:expr, ($($name:ident:$ty:ty = $arg:expr),*$(,)?) => $e:expr $(,)?) => { { @@ -75,11 +77,13 @@ macro_rules! assert_unsafe_precondition { } }; } -pub(crate) use assert_unsafe_precondition; +#[unstable(feature = "ub_checks", issue = "none")] +pub use assert_unsafe_precondition; /// Checking library UB is always enabled when UB-checking is done /// (and we use a reexport so that there is no unnecessary wrapper function). -pub(crate) use intrinsics::ub_checks as check_library_ub; +#[unstable(feature = "ub_checks", issue = "none")] +pub use intrinsics::ub_checks as check_library_ub; /// Determines whether we should check for language UB. /// diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 241a443fab96..3055c638e2cf 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -358,6 +358,7 @@ #![feature(str_internals)] #![feature(strict_provenance)] #![feature(strict_provenance_atomic_ptr)] +#![feature(ub_checks)] // tidy-alphabetical-end // // Library features (alloc): From d55e5b45007569c53bb86732d05ada08a1cd8ebd Mon Sep 17 00:00:00 2001 From: forcedebug Date: Tue, 23 Apr 2024 20:31:26 +0800 Subject: [PATCH 036/279] chore: fix some typos in comments Signed-off-by: forcedebug --- clippy_lints/src/implied_bounds_in_impls.rs | 2 +- clippy_lints/src/methods/unused_enumerate_index.rs | 2 +- clippy_lints/src/size_of_ref.rs | 2 +- tests/ui/mistyped_literal_suffix.fixed | 2 +- tests/ui/mistyped_literal_suffix.rs | 2 +- tests/ui/type_id_on_box_unfixable.rs | 2 +- util/gh-pages/script.js | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/implied_bounds_in_impls.rs b/clippy_lints/src/implied_bounds_in_impls.rs index 7b97fc15caaf..3bf8d6189558 100644 --- a/clippy_lints/src/implied_bounds_in_impls.rs +++ b/clippy_lints/src/implied_bounds_in_impls.rs @@ -24,7 +24,7 @@ declare_clippy_lint! { /// /// ### Limitations /// This lint does not check for implied bounds transitively. Meaning that - /// it does't check for implied bounds from supertraits of supertraits + /// it doesn't check for implied bounds from supertraits of supertraits /// (e.g. `trait A {} trait B: A {} trait C: B {}`, then having an `fn() -> impl A + C`) /// /// ### Example diff --git a/clippy_lints/src/methods/unused_enumerate_index.rs b/clippy_lints/src/methods/unused_enumerate_index.rs index e5cc898612e9..92f3ac5ff99b 100644 --- a/clippy_lints/src/methods/unused_enumerate_index.rs +++ b/clippy_lints/src/methods/unused_enumerate_index.rs @@ -78,7 +78,7 @@ pub(super) fn check(cx: &LateContext<'_>, call_expr: &Expr<'_>, recv: &Expr<'_>, && match_def_path(cx, enumerate_defid, &CORE_ITER_ENUMERATE_METHOD) { // Check if the tuple type was explicit. It may be the type system _needs_ the type of the element - // that would be explicited in the closure. + // that would be explicitly in the closure. let new_closure_param = match find_elem_explicit_type_span(closure.fn_decl) { // We have an explicit type. Get its snippet, that of the binding name, and do `binding: ty`. // Fallback to `..` if we fail getting either snippet. diff --git a/clippy_lints/src/size_of_ref.rs b/clippy_lints/src/size_of_ref.rs index 14ca7a3f0042..8d7f12af86e8 100644 --- a/clippy_lints/src/size_of_ref.rs +++ b/clippy_lints/src/size_of_ref.rs @@ -28,7 +28,7 @@ declare_clippy_lint! { /// fn size(&self) -> usize { /// // Note that `&self` as an argument is a `&&Foo`: Because `self` /// // is already a reference, `&self` is a double-reference. - /// // The return value of `size_of_val()` therefor is the + /// // The return value of `size_of_val()` therefore is the /// // size of the reference-type, not the size of `self`. /// std::mem::size_of_val(&self) /// } diff --git a/tests/ui/mistyped_literal_suffix.fixed b/tests/ui/mistyped_literal_suffix.fixed index 861764a2aeeb..b84b3dc349ec 100644 --- a/tests/ui/mistyped_literal_suffix.fixed +++ b/tests/ui/mistyped_literal_suffix.fixed @@ -32,7 +32,7 @@ fn main() { // testing that the suggestion actually fits in its type let fail30 = 127_i8; // should be i8 let fail31 = 240_u8; // should be u8 - let ok32 = 360_8; // doesnt fit in either, should be ignored + let ok32 = 360_8; // doesn't fit in either, should be ignored let fail33 = 0x1234_i16; let fail34 = 0xABCD_u16; let ok35 = 0x12345_16; diff --git a/tests/ui/mistyped_literal_suffix.rs b/tests/ui/mistyped_literal_suffix.rs index 4a15c335fd89..a47a736067a8 100644 --- a/tests/ui/mistyped_literal_suffix.rs +++ b/tests/ui/mistyped_literal_suffix.rs @@ -32,7 +32,7 @@ fn main() { // testing that the suggestion actually fits in its type let fail30 = 127_8; // should be i8 let fail31 = 240_8; // should be u8 - let ok32 = 360_8; // doesnt fit in either, should be ignored + let ok32 = 360_8; // doesn't fit in either, should be ignored let fail33 = 0x1234_16; let fail34 = 0xABCD_16; let ok35 = 0x12345_16; diff --git a/tests/ui/type_id_on_box_unfixable.rs b/tests/ui/type_id_on_box_unfixable.rs index f6d09834adb1..67e398e604b4 100644 --- a/tests/ui/type_id_on_box_unfixable.rs +++ b/tests/ui/type_id_on_box_unfixable.rs @@ -19,7 +19,7 @@ where impl NormalTrait for T {} fn main() { - // (currently we don't look deeper than one level into the supertrait hierachy, but we probably + // (currently we don't look deeper than one level into the supertrait hierarchy, but we probably // could) let b: Box = Box::new(1); let _ = b.type_id(); diff --git a/util/gh-pages/script.js b/util/gh-pages/script.js index f59245e556cd..c63edd5bf709 100644 --- a/util/gh-pages/script.js +++ b/util/gh-pages/script.js @@ -415,7 +415,7 @@ let terms = searchStr.split(" "); let docsLowerCase = lint.docs.toLowerCase(); for (index = 0; index < terms.length; index++) { - // This is more likely and will therefor be checked first + // This is more likely and will therefore be checked first if (docsLowerCase.indexOf(terms[index]) !== -1) { continue; } From 899e3ae86b082dd5d314fe90ba26510db64e1d51 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 23 Apr 2024 09:06:52 -0700 Subject: [PATCH 037/279] bootstrap: keep all cargo test files in dist rustc-src Cargo tests use some files that we would otherwise exclude, especially the `cargo init` tests that are meant to deal with pre-existing `.git` and `.hg` repos and their ignore files. Keeping these in our dist tarball doesn't take much space, and allows distro builds to run these tests successfully. --- src/bootstrap/src/core/build_steps/dist.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 0eca20901b76..770a5cdb232d 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -830,6 +830,12 @@ fn copy_src_dirs( return false; } + // Cargo tests use some files like `.gitignore` that we would otherwise exclude. + const CARGO_TESTS: &[&str] = &["tools/cargo/tests", "tools\\cargo\\tests"]; + if CARGO_TESTS.iter().any(|path| spath.contains(path)) { + return true; + } + let full_path = Path::new(dir).join(path); if exclude_dirs.iter().any(|excl| full_path == Path::new(excl)) { return false; From 107e44b76ff76805bc9bea5dc2e4ba96354ab374 Mon Sep 17 00:00:00 2001 From: Luv-Ray Date: Wed, 24 Apr 2024 10:54:08 +0800 Subject: [PATCH 038/279] [`non_canonical_partial_ord_impl`]: Fix emitting warnings which conflict with `needless_return` --- clippy_lints/src/non_canonical_impls.rs | 46 ++++++++++++++----- tests/ui/non_canonical_partial_ord_impl.fixed | 18 ++++++++ tests/ui/non_canonical_partial_ord_impl.rs | 18 ++++++++ 3 files changed, 71 insertions(+), 11 deletions(-) diff --git a/clippy_lints/src/non_canonical_impls.rs b/clippy_lints/src/non_canonical_impls.rs index fd3985a5dafc..932d6fe54d66 100644 --- a/clippy_lints/src/non_canonical_impls.rs +++ b/clippy_lints/src/non_canonical_impls.rs @@ -182,17 +182,17 @@ impl LateLintPass<'_> for NonCanonicalImpls { if block.stmts.is_empty() && let Some(expr) = block.expr - && let ExprKind::Call( - Expr { - kind: ExprKind::Path(some_path), - hir_id: some_hir_id, - .. - }, - [cmp_expr], - ) = expr.kind - && is_res_lang_ctor(cx, cx.qpath_res(some_path, *some_hir_id), LangItem::OptionSome) - // Fix #11178, allow `Self::cmp(self, ..)` too - && self_cmp_call(cx, cmp_expr, impl_item.owner_id.def_id, &mut needs_fully_qualified) + && expr_is_cmp(cx, &expr.kind, impl_item, &mut needs_fully_qualified) + { + } + // Fix #12683, allow [`needless_return`] here + else if block.expr.is_none() + && let Some(stmt) = block.stmts.first() + && let rustc_hir::StmtKind::Semi(Expr { + kind: ExprKind::Ret(Some(Expr { kind: ret_kind, .. })), + .. + }) = stmt.kind + && expr_is_cmp(cx, ret_kind, impl_item, &mut needs_fully_qualified) { } else { // If `Self` and `Rhs` are not the same type, bail. This makes creating a valid @@ -245,6 +245,30 @@ impl LateLintPass<'_> for NonCanonicalImpls { } } +/// Return true if `expr_kind` is a `cmp` call. +fn expr_is_cmp<'tcx>( + cx: &LateContext<'tcx>, + expr_kind: &'tcx ExprKind<'tcx>, + impl_item: &ImplItem<'_>, + needs_fully_qualified: &mut bool, +) -> bool { + if let ExprKind::Call( + Expr { + kind: ExprKind::Path(some_path), + hir_id: some_hir_id, + .. + }, + [cmp_expr], + ) = expr_kind + { + is_res_lang_ctor(cx, cx.qpath_res(some_path, *some_hir_id), LangItem::OptionSome) + // Fix #11178, allow `Self::cmp(self, ..)` too + && self_cmp_call(cx, cmp_expr, impl_item.owner_id.def_id, needs_fully_qualified) + } else { + false + } +} + /// Returns whether this is any of `self.cmp(..)`, `Self::cmp(self, ..)` or `Ord::cmp(self, ..)`. fn self_cmp_call<'tcx>( cx: &LateContext<'tcx>, diff --git a/tests/ui/non_canonical_partial_ord_impl.fixed b/tests/ui/non_canonical_partial_ord_impl.fixed index db55cc094e3a..d444a753697f 100644 --- a/tests/ui/non_canonical_partial_ord_impl.fixed +++ b/tests/ui/non_canonical_partial_ord_impl.fixed @@ -142,3 +142,21 @@ impl PartialOrd for H { Some(Ord::cmp(self, other)) } } + +// #12683, do not lint + +#[derive(Eq, PartialEq)] +struct I(u32); + +impl Ord for I { + fn cmp(&self, other: &Self) -> Ordering { + todo!(); + } +} + +impl PartialOrd for I { + #[allow(clippy::needless_return)] + fn partial_cmp(&self, other: &Self) -> Option { + return Some(self.cmp(other)); + } +} diff --git a/tests/ui/non_canonical_partial_ord_impl.rs b/tests/ui/non_canonical_partial_ord_impl.rs index 52f4b85b9172..dc6c4354604d 100644 --- a/tests/ui/non_canonical_partial_ord_impl.rs +++ b/tests/ui/non_canonical_partial_ord_impl.rs @@ -146,3 +146,21 @@ impl PartialOrd for H { Some(Ord::cmp(self, other)) } } + +// #12683, do not lint + +#[derive(Eq, PartialEq)] +struct I(u32); + +impl Ord for I { + fn cmp(&self, other: &Self) -> Ordering { + todo!(); + } +} + +impl PartialOrd for I { + #[allow(clippy::needless_return)] + fn partial_cmp(&self, other: &Self) -> Option { + return Some(self.cmp(other)); + } +} From 3fc9537624b29ce8c635b4019c596f72e679cd49 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 11 Apr 2024 13:15:34 +0000 Subject: [PATCH 039/279] Error on using `yield` without also using `#[coroutine]` on the closure And suggest adding the `#[coroutine]` to the closure --- tests/ui/crashes/ice-5238.rs | 4 ++-- tests/ui/large_futures.fixed | 1 - tests/ui/large_futures.rs | 1 - tests/ui/large_futures.stderr | 16 ++++++++-------- tests/ui/redundant_locals.rs | 6 +++--- 5 files changed, 13 insertions(+), 15 deletions(-) diff --git a/tests/ui/crashes/ice-5238.rs b/tests/ui/crashes/ice-5238.rs index b1fc3fb9d251..fe03a39ad1ba 100644 --- a/tests/ui/crashes/ice-5238.rs +++ b/tests/ui/crashes/ice-5238.rs @@ -1,9 +1,9 @@ // Regression test for #5238 / https://github.com/rust-lang/rust/pull/69562 -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] fn main() { - let _ = || { + let _ = #[coroutine] || { yield; }; } diff --git a/tests/ui/large_futures.fixed b/tests/ui/large_futures.fixed index aa8c3021b970..1e87859f4526 100644 --- a/tests/ui/large_futures.fixed +++ b/tests/ui/large_futures.fixed @@ -1,4 +1,3 @@ -#![feature(coroutines)] #![warn(clippy::large_futures)] #![allow(clippy::never_loop)] #![allow(clippy::future_not_send)] diff --git a/tests/ui/large_futures.rs b/tests/ui/large_futures.rs index fc6ea458d3db..3f4ea2ebf8bb 100644 --- a/tests/ui/large_futures.rs +++ b/tests/ui/large_futures.rs @@ -1,4 +1,3 @@ -#![feature(coroutines)] #![warn(clippy::large_futures)] #![allow(clippy::never_loop)] #![allow(clippy::future_not_send)] diff --git a/tests/ui/large_futures.stderr b/tests/ui/large_futures.stderr index 5709c7b77a0a..00082e579c59 100644 --- a/tests/ui/large_futures.stderr +++ b/tests/ui/large_futures.stderr @@ -1,5 +1,5 @@ error: large future with a size of 16385 bytes - --> tests/ui/large_futures.rs:11:9 + --> tests/ui/large_futures.rs:10:9 | LL | big_fut([0u8; 1024 * 16]).await; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(big_fut([0u8; 1024 * 16]))` @@ -8,37 +8,37 @@ LL | big_fut([0u8; 1024 * 16]).await; = help: to override `-D warnings` add `#[allow(clippy::large_futures)]` error: large future with a size of 16386 bytes - --> tests/ui/large_futures.rs:15:5 + --> tests/ui/large_futures.rs:14:5 | LL | f.await | ^ help: consider `Box::pin` on it: `Box::pin(f)` error: large future with a size of 16387 bytes - --> tests/ui/large_futures.rs:20:9 + --> tests/ui/large_futures.rs:19:9 | LL | wait().await; | ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())` error: large future with a size of 16387 bytes - --> tests/ui/large_futures.rs:25:13 + --> tests/ui/large_futures.rs:24:13 | LL | wait().await; | ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())` error: large future with a size of 65540 bytes - --> tests/ui/large_futures.rs:33:5 + --> tests/ui/large_futures.rs:32:5 | LL | foo().await; | ^^^^^ help: consider `Box::pin` on it: `Box::pin(foo())` error: large future with a size of 49159 bytes - --> tests/ui/large_futures.rs:35:5 + --> tests/ui/large_futures.rs:34:5 | LL | calls_fut(fut).await; | ^^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(calls_fut(fut))` error: large future with a size of 65540 bytes - --> tests/ui/large_futures.rs:48:5 + --> tests/ui/large_futures.rs:47:5 | LL | / async { LL | | @@ -59,7 +59,7 @@ LL + }) | error: large future with a size of 65540 bytes - --> tests/ui/large_futures.rs:60:13 + --> tests/ui/large_futures.rs:59:13 | LL | / async { LL | | let x = [0i32; 1024 * 16]; diff --git a/tests/ui/redundant_locals.rs b/tests/ui/redundant_locals.rs index f6909828aa9a..e9d77182a919 100644 --- a/tests/ui/redundant_locals.rs +++ b/tests/ui/redundant_locals.rs @@ -1,7 +1,7 @@ //@aux-build:proc_macros.rs #![allow(unused, clippy::no_effect, clippy::needless_pass_by_ref_mut)] #![warn(clippy::redundant_locals)] -#![feature(async_closure, coroutines)] +#![feature(async_closure, coroutines, stmt_expr_attributes)] extern crate proc_macros; use proc_macros::{external, with_span}; @@ -191,11 +191,11 @@ fn issue12225() { let v4 = v4; dbg!(&v4); }); - assert_static(static || { + assert_static(#[coroutine] static || { let v5 = v5; yield; }); - assert_static(|| { + assert_static(#[coroutine] || { let v6 = v6; yield; }); From 7d9f970d4eebd1b47a3c1e7bfb3045c6a3ee1283 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Fri, 19 Apr 2024 17:01:35 +0100 Subject: [PATCH 040/279] Fix and bless clippy tests --- tests/ui-toml/suppress_lint_in_const/test.rs | 1 - .../suppress_lint_in_const/test.stderr | 12 ++--- tests/ui/arithmetic_side_effects.rs | 2 +- tests/ui/bool_to_int_with_if.fixed | 2 +- tests/ui/bool_to_int_with_if.rs | 2 +- tests/ui/const_is_empty.rs | 1 - tests/ui/const_is_empty.stderr | 52 +++++++++---------- tests/ui/indexing_slicing_index.rs | 1 - tests/ui/indexing_slicing_index.stderr | 32 ++++++------ tests/ui/manual_float_methods.rs | 1 - tests/ui/manual_float_methods.stderr | 12 ++--- tests/ui/never_loop.rs | 2 +- tests/ui/panicking_macros.rs | 1 - tests/ui/panicking_macros.stderr | 32 ++++++------ 14 files changed, 74 insertions(+), 79 deletions(-) diff --git a/tests/ui-toml/suppress_lint_in_const/test.rs b/tests/ui-toml/suppress_lint_in_const/test.rs index 4ae75544c60c..232bccf6a154 100644 --- a/tests/ui-toml/suppress_lint_in_const/test.rs +++ b/tests/ui-toml/suppress_lint_in_const/test.rs @@ -1,4 +1,3 @@ -#![feature(inline_const)] #![warn(clippy::indexing_slicing)] // We also check the out_of_bounds_indexing lint here, because it lints similar things and // we want to avoid false positives. diff --git a/tests/ui-toml/suppress_lint_in_const/test.stderr b/tests/ui-toml/suppress_lint_in_const/test.stderr index 120f5c35cb03..5ce2ed2ffaee 100644 --- a/tests/ui-toml/suppress_lint_in_const/test.stderr +++ b/tests/ui-toml/suppress_lint_in_const/test.stderr @@ -1,5 +1,5 @@ error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:27:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:26:5 | LL | x[index]; | ^^^^^^^^ @@ -9,7 +9,7 @@ LL | x[index]; = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]` error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:42:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:41:5 | LL | v[0]; | ^^^^ @@ -17,7 +17,7 @@ LL | v[0]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:43:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:42:5 | LL | v[10]; | ^^^^^ @@ -25,7 +25,7 @@ LL | v[10]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:44:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:43:5 | LL | v[1 << 3]; | ^^^^^^^^^ @@ -33,7 +33,7 @@ LL | v[1 << 3]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:50:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:49:5 | LL | v[N]; | ^^^^ @@ -41,7 +41,7 @@ LL | v[N]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:51:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:50:5 | LL | v[M]; | ^^^^ diff --git a/tests/ui/arithmetic_side_effects.rs b/tests/ui/arithmetic_side_effects.rs index b454c29aef4d..fdec14a1528f 100644 --- a/tests/ui/arithmetic_side_effects.rs +++ b/tests/ui/arithmetic_side_effects.rs @@ -10,7 +10,7 @@ arithmetic_overflow, unconditional_panic )] -#![feature(const_mut_refs, inline_const)] +#![feature(const_mut_refs)] #![warn(clippy::arithmetic_side_effects)] extern crate proc_macro_derive; diff --git a/tests/ui/bool_to_int_with_if.fixed b/tests/ui/bool_to_int_with_if.fixed index 167263d31df8..f7dad28b0369 100644 --- a/tests/ui/bool_to_int_with_if.fixed +++ b/tests/ui/bool_to_int_with_if.fixed @@ -1,4 +1,4 @@ -#![feature(let_chains, inline_const)] +#![feature(let_chains)] #![warn(clippy::bool_to_int_with_if)] #![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)] diff --git a/tests/ui/bool_to_int_with_if.rs b/tests/ui/bool_to_int_with_if.rs index f3f055eb7f06..d22871d2c8f2 100644 --- a/tests/ui/bool_to_int_with_if.rs +++ b/tests/ui/bool_to_int_with_if.rs @@ -1,4 +1,4 @@ -#![feature(let_chains, inline_const)] +#![feature(let_chains)] #![warn(clippy::bool_to_int_with_if)] #![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)] diff --git a/tests/ui/const_is_empty.rs b/tests/ui/const_is_empty.rs index ae37a82e4f93..04e0de91ecfb 100644 --- a/tests/ui/const_is_empty.rs +++ b/tests/ui/const_is_empty.rs @@ -1,4 +1,3 @@ -#![feature(inline_const)] #![warn(clippy::const_is_empty)] #![allow(clippy::needless_late_init, unused_must_use)] diff --git a/tests/ui/const_is_empty.stderr b/tests/ui/const_is_empty.stderr index 0e09da77bb46..7f80b520b1a4 100644 --- a/tests/ui/const_is_empty.stderr +++ b/tests/ui/const_is_empty.stderr @@ -1,5 +1,5 @@ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:6:8 + --> tests/ui/const_is_empty.rs:5:8 | LL | if "".is_empty() { | ^^^^^^^^^^^^^ @@ -8,151 +8,151 @@ LL | if "".is_empty() { = help: to override `-D warnings` add `#[allow(clippy::const_is_empty)]` error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:9:8 + --> tests/ui/const_is_empty.rs:8:8 | LL | if "foobar".is_empty() { | ^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:15:8 + --> tests/ui/const_is_empty.rs:14:8 | LL | if b"".is_empty() { | ^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:18:8 + --> tests/ui/const_is_empty.rs:17:8 | LL | if b"foobar".is_empty() { | ^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:35:8 + --> tests/ui/const_is_empty.rs:34:8 | LL | if empty2.is_empty() { | ^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:38:8 + --> tests/ui/const_is_empty.rs:37:8 | LL | if non_empty2.is_empty() { | ^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:60:13 + --> tests/ui/const_is_empty.rs:59:13 | LL | let _ = EMPTY_STR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:62:13 + --> tests/ui/const_is_empty.rs:61:13 | LL | let _ = NON_EMPTY_STR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:64:13 + --> tests/ui/const_is_empty.rs:63:13 | LL | let _ = EMPTY_BSTR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:66:13 + --> tests/ui/const_is_empty.rs:65:13 | LL | let _ = NON_EMPTY_BSTR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:68:13 + --> tests/ui/const_is_empty.rs:67:13 | LL | let _ = EMPTY_ARRAY.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:70:13 + --> tests/ui/const_is_empty.rs:69:13 | LL | let _ = EMPTY_ARRAY_REPEAT.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:72:13 + --> tests/ui/const_is_empty.rs:71:13 | LL | let _ = EMPTY_U8_SLICE.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:74:13 + --> tests/ui/const_is_empty.rs:73:13 | LL | let _ = NON_EMPTY_U8_SLICE.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:76:13 + --> tests/ui/const_is_empty.rs:75:13 | LL | let _ = NON_EMPTY_ARRAY.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:78:13 + --> tests/ui/const_is_empty.rs:77:13 | LL | let _ = NON_EMPTY_ARRAY_REPEAT.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:80:13 + --> tests/ui/const_is_empty.rs:79:13 | LL | let _ = EMPTY_REF_ARRAY.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:82:13 + --> tests/ui/const_is_empty.rs:81:13 | LL | let _ = NON_EMPTY_REF_ARRAY.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:84:13 + --> tests/ui/const_is_empty.rs:83:13 | LL | let _ = EMPTY_SLICE.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:86:13 + --> tests/ui/const_is_empty.rs:85:13 | LL | let _ = NON_EMPTY_SLICE.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:88:13 + --> tests/ui/const_is_empty.rs:87:13 | LL | let _ = NON_EMPTY_SLICE_REPEAT.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:94:13 + --> tests/ui/const_is_empty.rs:93:13 | LL | let _ = value.is_empty(); | ^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:97:13 + --> tests/ui/const_is_empty.rs:96:13 | LL | let _ = x.is_empty(); | ^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:99:13 + --> tests/ui/const_is_empty.rs:98:13 | LL | let _ = "".is_empty(); | ^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:101:13 + --> tests/ui/const_is_empty.rs:100:13 | LL | let _ = b"".is_empty(); | ^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:155:13 + --> tests/ui/const_is_empty.rs:154:13 | LL | let _ = val.is_empty(); | ^^^^^^^^^^^^^^ diff --git a/tests/ui/indexing_slicing_index.rs b/tests/ui/indexing_slicing_index.rs index 27ee2f91594b..2e726141649e 100644 --- a/tests/ui/indexing_slicing_index.rs +++ b/tests/ui/indexing_slicing_index.rs @@ -1,6 +1,5 @@ //@compile-flags: -Zdeduplicate-diagnostics=yes -#![feature(inline_const)] #![warn(clippy::indexing_slicing)] // We also check the out_of_bounds_indexing lint here, because it lints similar things and // we want to avoid false positives. diff --git a/tests/ui/indexing_slicing_index.stderr b/tests/ui/indexing_slicing_index.stderr index 5f62ec9b5565..386f91becf14 100644 --- a/tests/ui/indexing_slicing_index.stderr +++ b/tests/ui/indexing_slicing_index.stderr @@ -1,5 +1,5 @@ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:16:20 + --> tests/ui/indexing_slicing_index.rs:15:20 | LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-restriction-lint-in-const` default is false. | ^^^^^^^^^^ @@ -10,19 +10,19 @@ LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-re = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]` error[E0080]: evaluation of `main::{constant#3}` failed - --> tests/ui/indexing_slicing_index.rs:48:14 + --> tests/ui/indexing_slicing_index.rs:47:14 | LL | const { &ARR[idx4()] }; | ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4 note: erroneous constant encountered - --> tests/ui/indexing_slicing_index.rs:48:5 + --> tests/ui/indexing_slicing_index.rs:47:5 | LL | const { &ARR[idx4()] }; | ^^^^^^^^^^^^^^^^^^^^^^ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:29:5 + --> tests/ui/indexing_slicing_index.rs:28:5 | LL | x[index]; | ^^^^^^^^ @@ -30,7 +30,7 @@ LL | x[index]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:32:5 + --> tests/ui/indexing_slicing_index.rs:31:5 | LL | x[4]; | ^^^^ @@ -39,13 +39,13 @@ LL | x[4]; = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]` error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:34:5 + --> tests/ui/indexing_slicing_index.rs:33:5 | LL | x[1 << 3]; | ^^^^^^^^^ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:45:14 + --> tests/ui/indexing_slicing_index.rs:44:14 | LL | const { &ARR[idx()] }; | ^^^^^^^^^^ @@ -54,7 +54,7 @@ LL | const { &ARR[idx()] }; = note: the suggestion might not be applicable in constant blocks error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:48:14 + --> tests/ui/indexing_slicing_index.rs:47:14 | LL | const { &ARR[idx4()] }; | ^^^^^^^^^^^ @@ -63,13 +63,13 @@ LL | const { &ARR[idx4()] }; = note: the suggestion might not be applicable in constant blocks error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:55:5 + --> tests/ui/indexing_slicing_index.rs:54:5 | LL | y[4]; | ^^^^ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:58:5 + --> tests/ui/indexing_slicing_index.rs:57:5 | LL | v[0]; | ^^^^ @@ -77,7 +77,7 @@ LL | v[0]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:60:5 + --> tests/ui/indexing_slicing_index.rs:59:5 | LL | v[10]; | ^^^^^ @@ -85,7 +85,7 @@ LL | v[10]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:62:5 + --> tests/ui/indexing_slicing_index.rs:61:5 | LL | v[1 << 3]; | ^^^^^^^^^ @@ -93,13 +93,13 @@ LL | v[1 << 3]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:70:5 + --> tests/ui/indexing_slicing_index.rs:69:5 | LL | x[N]; | ^^^^ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:73:5 + --> tests/ui/indexing_slicing_index.rs:72:5 | LL | v[N]; | ^^^^ @@ -107,7 +107,7 @@ LL | v[N]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:75:5 + --> tests/ui/indexing_slicing_index.rs:74:5 | LL | v[M]; | ^^^^ @@ -115,7 +115,7 @@ LL | v[M]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:79:13 + --> tests/ui/indexing_slicing_index.rs:78:13 | LL | let _ = x[4]; | ^^^^ diff --git a/tests/ui/manual_float_methods.rs b/tests/ui/manual_float_methods.rs index f3e95d6807d3..80781ecda721 100644 --- a/tests/ui/manual_float_methods.rs +++ b/tests/ui/manual_float_methods.rs @@ -2,7 +2,6 @@ //@aux-build:proc_macros.rs #![allow(clippy::needless_if, unused)] #![warn(clippy::manual_is_infinite, clippy::manual_is_finite)] -#![feature(inline_const)] #[macro_use] extern crate proc_macros; diff --git a/tests/ui/manual_float_methods.stderr b/tests/ui/manual_float_methods.stderr index dae96839262d..930df0b97cb3 100644 --- a/tests/ui/manual_float_methods.stderr +++ b/tests/ui/manual_float_methods.stderr @@ -1,5 +1,5 @@ error: manually checking if a float is infinite - --> tests/ui/manual_float_methods.rs:23:8 + --> tests/ui/manual_float_methods.rs:22:8 | LL | if x == f32::INFINITY || x == f32::NEG_INFINITY {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()` @@ -8,7 +8,7 @@ LL | if x == f32::INFINITY || x == f32::NEG_INFINITY {} = help: to override `-D warnings` add `#[allow(clippy::manual_is_infinite)]` error: manually checking if a float is finite - --> tests/ui/manual_float_methods.rs:24:8 + --> tests/ui/manual_float_methods.rs:23:8 | LL | if x != f32::INFINITY && x != f32::NEG_INFINITY {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -29,13 +29,13 @@ LL | if !x.is_infinite() {} | ~~~~~~~~~~~~~~~~ error: manually checking if a float is infinite - --> tests/ui/manual_float_methods.rs:25:8 + --> tests/ui/manual_float_methods.rs:24:8 | LL | if x == INFINITE || x == NEG_INFINITE {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()` error: manually checking if a float is finite - --> tests/ui/manual_float_methods.rs:26:8 + --> tests/ui/manual_float_methods.rs:25:8 | LL | if x != INFINITE && x != NEG_INFINITE {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | if !x.is_infinite() {} | ~~~~~~~~~~~~~~~~ error: manually checking if a float is infinite - --> tests/ui/manual_float_methods.rs:28:8 + --> tests/ui/manual_float_methods.rs:27:8 | LL | if x == f64::INFINITY || x == f64::NEG_INFINITY {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()` error: manually checking if a float is finite - --> tests/ui/manual_float_methods.rs:29:8 + --> tests/ui/manual_float_methods.rs:28:8 | LL | if x != f64::INFINITY && x != f64::NEG_INFINITY {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/never_loop.rs b/tests/ui/never_loop.rs index 92f173d9db4a..93c69209c698 100644 --- a/tests/ui/never_loop.rs +++ b/tests/ui/never_loop.rs @@ -1,4 +1,4 @@ -#![feature(inline_const, try_blocks)] +#![feature(try_blocks)] #![allow( clippy::eq_op, clippy::single_match, diff --git a/tests/ui/panicking_macros.rs b/tests/ui/panicking_macros.rs index dccfbd409e50..2bbf5792ec4c 100644 --- a/tests/ui/panicking_macros.rs +++ b/tests/ui/panicking_macros.rs @@ -1,5 +1,4 @@ #![allow(clippy::assertions_on_constants, clippy::eq_op, clippy::let_unit_value)] -#![feature(inline_const)] #![warn(clippy::unimplemented, clippy::unreachable, clippy::todo, clippy::panic)] extern crate core; diff --git a/tests/ui/panicking_macros.stderr b/tests/ui/panicking_macros.stderr index 06025859c0c6..7c0f0a7d3764 100644 --- a/tests/ui/panicking_macros.stderr +++ b/tests/ui/panicking_macros.stderr @@ -1,5 +1,5 @@ error: `panic` should not be present in production code - --> tests/ui/panicking_macros.rs:23:5 + --> tests/ui/panicking_macros.rs:22:5 | LL | panic!(); | ^^^^^^^^ @@ -8,19 +8,19 @@ LL | panic!(); = help: to override `-D warnings` add `#[allow(clippy::panic)]` error: `panic` should not be present in production code - --> tests/ui/panicking_macros.rs:26:5 + --> tests/ui/panicking_macros.rs:25:5 | LL | panic!("message"); | ^^^^^^^^^^^^^^^^^ error: `panic` should not be present in production code - --> tests/ui/panicking_macros.rs:28:5 + --> tests/ui/panicking_macros.rs:27:5 | LL | panic!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `todo` should not be present in production code - --> tests/ui/panicking_macros.rs:35:5 + --> tests/ui/panicking_macros.rs:34:5 | LL | todo!(); | ^^^^^^^ @@ -29,19 +29,19 @@ LL | todo!(); = help: to override `-D warnings` add `#[allow(clippy::todo)]` error: `todo` should not be present in production code - --> tests/ui/panicking_macros.rs:38:5 + --> tests/ui/panicking_macros.rs:37:5 | LL | todo!("message"); | ^^^^^^^^^^^^^^^^ error: `todo` should not be present in production code - --> tests/ui/panicking_macros.rs:40:5 + --> tests/ui/panicking_macros.rs:39:5 | LL | todo!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `unimplemented` should not be present in production code - --> tests/ui/panicking_macros.rs:47:5 + --> tests/ui/panicking_macros.rs:46:5 | LL | unimplemented!(); | ^^^^^^^^^^^^^^^^ @@ -50,19 +50,19 @@ LL | unimplemented!(); = help: to override `-D warnings` add `#[allow(clippy::unimplemented)]` error: `unimplemented` should not be present in production code - --> tests/ui/panicking_macros.rs:50:5 + --> tests/ui/panicking_macros.rs:49:5 | LL | unimplemented!("message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `unimplemented` should not be present in production code - --> tests/ui/panicking_macros.rs:52:5 + --> tests/ui/panicking_macros.rs:51:5 | LL | unimplemented!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: usage of the `unreachable!` macro - --> tests/ui/panicking_macros.rs:59:5 + --> tests/ui/panicking_macros.rs:58:5 | LL | unreachable!(); | ^^^^^^^^^^^^^^ @@ -71,37 +71,37 @@ LL | unreachable!(); = help: to override `-D warnings` add `#[allow(clippy::unreachable)]` error: usage of the `unreachable!` macro - --> tests/ui/panicking_macros.rs:62:5 + --> tests/ui/panicking_macros.rs:61:5 | LL | unreachable!("message"); | ^^^^^^^^^^^^^^^^^^^^^^^ error: usage of the `unreachable!` macro - --> tests/ui/panicking_macros.rs:64:5 + --> tests/ui/panicking_macros.rs:63:5 | LL | unreachable!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `panic` should not be present in production code - --> tests/ui/panicking_macros.rs:71:5 + --> tests/ui/panicking_macros.rs:70:5 | LL | panic!(); | ^^^^^^^^ error: `todo` should not be present in production code - --> tests/ui/panicking_macros.rs:73:5 + --> tests/ui/panicking_macros.rs:72:5 | LL | todo!(); | ^^^^^^^ error: `unimplemented` should not be present in production code - --> tests/ui/panicking_macros.rs:75:5 + --> tests/ui/panicking_macros.rs:74:5 | LL | unimplemented!(); | ^^^^^^^^^^^^^^^^ error: usage of the `unreachable!` macro - --> tests/ui/panicking_macros.rs:77:5 + --> tests/ui/panicking_macros.rs:76:5 | LL | unreachable!(); | ^^^^^^^^^^^^^^ From 0c0833d75035d2f443851147f766738f42b505e0 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 24 Apr 2024 19:56:56 +0300 Subject: [PATCH 041/279] resolve: Remove two cases of misleading macro call visiting Macro calls are ephemeral, they should not add anything to the definition tree, even if their AST could contains something with identity. Thankfully, macro call AST cannot contain anything like that, so these walks are just noops. In majority of other places in def_collector / build_reduced_graph they are already not visited. (Also, a minor match reformatting is included.) --- compiler/rustc_resolve/src/build_reduced_graph.rs | 6 +----- compiler/rustc_resolve/src/def_collector.rs | 9 ++------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 1b6387acf71e..a33d45990e78 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1304,11 +1304,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { visit::walk_item(self, item); macro_rules_scope } - ItemKind::MacCall(..) => { - let macro_rules_scope = self.visit_invoc_in_module(item.id); - visit::walk_item(self, item); - macro_rules_scope - } + ItemKind::MacCall(..) => self.visit_invoc_in_module(item.id), _ => { let orig_macro_rules_scope = self.parent_scope.macro_rules; self.build_reduced_graph_for_item(item); diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index bef95aca0d1c..c29131a5fb1e 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -136,14 +136,9 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { opt_macro_data = Some(macro_data); DefKind::Macro(macro_kind) } - ItemKind::MacCall(..) => { - visit::walk_item(self, i); - return self.visit_macro_invoc(i.id); - } ItemKind::GlobalAsm(..) => DefKind::GlobalAsm, - ItemKind::Use(..) => { - return visit::walk_item(self, i); - } + ItemKind::Use(..) => return visit::walk_item(self, i), + ItemKind::MacCall(..) => return self.visit_macro_invoc(i.id), }; let def_id = self.create_def(i.id, i.ident.name, def_kind, i.span); From a51ad7971261963906ffe37710610fa3fbfba723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Tue, 23 Apr 2024 20:38:54 +0200 Subject: [PATCH 042/279] Refactor dlltool searching code into separate function --- src/tools/compiletest/src/header/needs.rs | 65 ++++++------------- .../raw-dylib-cross-compilation/Makefile | 4 +- .../rfcs/rfc-2627-raw-dylib/dlltool-failed.rs | 2 - .../rfc-2627-raw-dylib/invalid-dlltool.rs | 3 +- 4 files changed, 21 insertions(+), 53 deletions(-) diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs index db154932d5b5..20d3fd473433 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/header/needs.rs @@ -119,16 +119,6 @@ pub(super) fn handle_needs( condition: config.debugger != Some(Debugger::Lldb) || config.lldb_native_rust, ignore_reason: "ignored on targets without Rust's LLDB", }, - Need { - name: "needs-i686-dlltool", - condition: cache.i686_dlltool, - ignore_reason: "ignored when dlltool for i686 is not present", - }, - Need { - name: "needs-x86_64-dlltool", - condition: cache.x86_64_dlltool, - ignore_reason: "ignored when dlltool for x86_64 is not present", - }, Need { name: "needs-dlltool", condition: cache.dlltool, @@ -218,27 +208,11 @@ pub(super) struct CachedNeedsConditions { profiler_support: bool, xray: bool, rust_lld: bool, - i686_dlltool: bool, - x86_64_dlltool: bool, dlltool: bool, } impl CachedNeedsConditions { pub(super) fn load(config: &Config) -> Self { - let path = std::env::var_os("PATH").expect("missing PATH environment variable"); - let path = std::env::split_paths(&path).collect::>(); - - // On Windows, dlltool.exe is used for all architectures. - #[cfg(windows)] - let dlltool = path.iter().any(|dir| dir.join("dlltool.exe").is_file()); - - // For non-Windows, there are architecture specific dlltool binaries. - #[cfg(not(windows))] - let i686_dlltool = path.iter().any(|dir| dir.join("i686-w64-mingw32-dlltool").is_file()); - #[cfg(not(windows))] - let x86_64_dlltool = - path.iter().any(|dir| dir.join("x86_64-w64-mingw32-dlltool").is_file()); - let target = &&*config.target; let sanitizers = &config.target_cfg().sanitizers; Self { @@ -278,26 +252,25 @@ impl CachedNeedsConditions { .join(if config.host.contains("windows") { "rust-lld.exe" } else { "rust-lld" }) .exists(), - #[cfg(windows)] - i686_dlltool: dlltool, - #[cfg(windows)] - x86_64_dlltool: dlltool, - #[cfg(windows)] - dlltool, - - // For non-Windows, there are architecture specific dlltool binaries. - #[cfg(not(windows))] - i686_dlltool, - #[cfg(not(windows))] - x86_64_dlltool, - #[cfg(not(windows))] - dlltool: if config.matches_arch("x86") { - i686_dlltool - } else if config.matches_arch("x86_64") { - x86_64_dlltool - } else { - false - }, + dlltool: find_dlltool(&config), } } } + +fn find_dlltool(config: &Config) -> bool { + let path = std::env::var_os("PATH").expect("missing PATH environment variable"); + let path = std::env::split_paths(&path).collect::>(); + + // On Windows, dlltool.exe is used for all architectures. + // For non-Windows, there are architecture specific dlltool binaries. + let dlltool_found = if cfg!(windows) { + path.iter().any(|dir| dir.join("dlltool.exe").is_file()) + } else if config.matches_arch("i686") { + path.iter().any(|dir| dir.join("i686-w64-mingw32-dlltool").is_file()) + } else if config.matches_arch("x86_64") { + path.iter().any(|dir| dir.join("x86_64-w64-mingw32-dlltool").is_file()) + } else { + false + }; + dlltool_found +} diff --git a/tests/run-make/raw-dylib-cross-compilation/Makefile b/tests/run-make/raw-dylib-cross-compilation/Makefile index a8f97edd6893..2524f8500e15 100644 --- a/tests/run-make/raw-dylib-cross-compilation/Makefile +++ b/tests/run-make/raw-dylib-cross-compilation/Makefile @@ -1,8 +1,6 @@ # Tests that raw-dylib cross compilation works correctly -# only-gnu -# needs-i686-dlltool -# needs-x86_64-dlltool +# needs-dlltool # i686 dlltool.exe can't product x64 binaries. # ignore-i686-pc-windows-gnu diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs b/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs index 5ff3cd25e67b..402efaf50271 100644 --- a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs +++ b/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs @@ -1,7 +1,5 @@ // Tests that dlltool failing to generate an import library will raise an error. -//@ only-gnu -//@ only-windows //@ needs-dlltool //@ compile-flags: --crate-type lib --emit link //@ normalize-stderr-test: "[^ ']*/dlltool.exe" -> "$$DLLTOOL" diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs b/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs index ac6a2998a476..bcf6dda7a44d 100644 --- a/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs +++ b/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs @@ -1,7 +1,6 @@ // Tests that failing to run dlltool will raise an error. -//@ only-gnu -//@ only-windows +//@ needs-dlltool //@ compile-flags: --crate-type lib --emit link -Cdlltool=does_not_exit.exe #[link(name = "foo", kind = "raw-dylib")] extern "C" { From b1fd4a7a49f9558b00aface02d6a5c5ccfa59d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Tue, 23 Apr 2024 20:47:21 +0200 Subject: [PATCH 043/279] Skip dlltool tests on non `*windows-gnu` targets --- src/tools/compiletest/src/header/needs.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs index 20d3fd473433..7bc7e4b86803 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/header/needs.rs @@ -261,6 +261,11 @@ fn find_dlltool(config: &Config) -> bool { let path = std::env::var_os("PATH").expect("missing PATH environment variable"); let path = std::env::split_paths(&path).collect::>(); + // dlltool is used ony by GNU based `*-*-windows-gnu` + if !(config.matches_os("windows") && config.matches_env("gnu") && config.matches_abi("")) { + return false; + } + // On Windows, dlltool.exe is used for all architectures. // For non-Windows, there are architecture specific dlltool binaries. let dlltool_found = if cfg!(windows) { From 69a4a46631c084a2fa863f71447d0547339a4c0d Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Wed, 24 Apr 2024 19:02:43 +0000 Subject: [PATCH 044/279] Rename `msrvs::ASSIGNING_CLONES` to `msrvs::CLONE_INTO` --- clippy_config/src/msrvs.rs | 2 +- clippy_lints/src/assigning_clones.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_config/src/msrvs.rs b/clippy_config/src/msrvs.rs index 59dd5b334b84..14808440d48d 100644 --- a/clippy_config/src/msrvs.rs +++ b/clippy_config/src/msrvs.rs @@ -23,7 +23,7 @@ msrv_aliases! { 1,70,0 { OPTION_RESULT_IS_VARIANT_AND, BINARY_HEAP_RETAIN } 1,68,0 { PATH_MAIN_SEPARATOR_STR } 1,65,0 { LET_ELSE, POINTER_CAST_CONSTNESS } - 1,63,0 { ASSIGNING_CLONES } + 1,63,0 { CLONE_INTO } 1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE } 1,59,0 { THREAD_LOCAL_INITIALIZER_CAN_BE_MADE_CONST } 1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY } diff --git a/clippy_lints/src/assigning_clones.rs b/clippy_lints/src/assigning_clones.rs index dc7f44af2b74..d88ca84fb97d 100644 --- a/clippy_lints/src/assigning_clones.rs +++ b/clippy_lints/src/assigning_clones.rs @@ -153,7 +153,7 @@ fn extract_call<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option< fn is_ok_to_suggest<'tcx>(cx: &LateContext<'tcx>, lhs: &Expr<'tcx>, call: &CallCandidate<'tcx>, msrv: &Msrv) -> bool { // For calls to .to_owned we suggest using .clone_into(), which was only stablilized in 1.63. // If the current MSRV is below that, don't suggest the lint. - if !msrv.meets(msrvs::ASSIGNING_CLONES) && matches!(call.target, TargetTrait::ToOwned) { + if !msrv.meets(msrvs::CLONE_INTO) && matches!(call.target, TargetTrait::ToOwned) { return false; } From 61cf00464e311b3dcf1a47b342c57978b1f40d88 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 13 Apr 2024 19:34:38 -0700 Subject: [PATCH 045/279] Stabilize Utf8Chunks --- library/alloc/src/lib.rs | 1 - library/alloc/src/str.rs | 2 +- library/alloc/src/string.rs | 4 +- library/core/src/str/lossy.rs | 74 +++++++++++++++++++---------- library/core/src/str/mod.rs | 2 +- library/core/tests/lib.rs | 1 - library/core/tests/str_lossy.rs | 6 +-- library/std/src/lib.rs | 1 - library/std/src/sys/os_str/bytes.rs | 6 +-- 9 files changed, 57 insertions(+), 40 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index dec04d7e421e..7d71f10e876e 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -163,7 +163,6 @@ #![feature(tuple_trait)] #![feature(unicode_internals)] #![feature(unsize)] -#![feature(utf8_chunks)] #![feature(vec_pop_if)] // tidy-alphabetical-end // diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index ade114678b7f..d88639c4092e 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -53,7 +53,7 @@ pub use core::str::{RSplit, Split}; pub use core::str::{RSplitN, SplitN}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::str::{RSplitTerminator, SplitTerminator}; -#[unstable(feature = "utf8_chunks", issue = "99543")] +#[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] pub use core::str::{Utf8Chunk, Utf8Chunks}; /// Note: `str` in `Concat` is not meaningful here. diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 5d552c8f15c6..29664fc3dfd5 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -58,8 +58,6 @@ use core::ops::{self, Range, RangeBounds}; use core::ptr; use core::slice; use core::str::pattern::Pattern; -#[cfg(not(no_global_oom_handling))] -use core::str::Utf8Chunks; #[cfg(not(no_global_oom_handling))] use crate::borrow::{Cow, ToOwned}; @@ -633,7 +631,7 @@ impl String { #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str> { - let mut iter = Utf8Chunks::new(v); + let mut iter = v.utf8_chunks(); let first_valid = if let Some(chunk) = iter.next() { let valid = chunk.valid(); diff --git a/library/core/src/str/lossy.rs b/library/core/src/str/lossy.rs index 59f873d1268c..f8ecf1f3a7c5 100644 --- a/library/core/src/str/lossy.rs +++ b/library/core/src/str/lossy.rs @@ -6,6 +6,46 @@ use crate::iter::FusedIterator; use super::from_utf8_unchecked; use super::validations::utf8_char_width; +impl [u8] { + /// Creates an iterator over the contiguous valid UTF-8 ranges of this + /// slice, and the non-UTF-8 fragments in between. + /// + /// # Examples + /// + /// This function formats arbitrary but mostly-UTF-8 bytes into Rust source + /// code in the form of a C-string literal (`c"..."`). + /// + /// ``` + /// use std::fmt::Write as _; + /// + /// pub fn cstr_literal(bytes: &[u8]) -> String { + /// let mut repr = String::new(); + /// repr.push_str("c\""); + /// for chunk in bytes.utf8_chunks() { + /// for ch in chunk.valid().chars() { + /// // Escapes \0, \t, \r, \n, \\, \', \", and uses \u{...} for non-printable characters. + /// write!(repr, "{}", ch.escape_debug()).unwrap(); + /// } + /// for byte in chunk.invalid() { + /// write!(repr, "\\x{:02X}", byte).unwrap(); + /// } + /// } + /// repr.push('"'); + /// repr + /// } + /// + /// fn main() { + /// let lit = cstr_literal(b"\xferris the \xf0\x9f\xa6\x80\x07"); + /// let expected = stringify!(c"\xFErris the 🦀\u{7}"); + /// assert_eq!(lit, expected); + /// } + /// ``` + #[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] + pub fn utf8_chunks(&self) -> Utf8Chunks<'_> { + Utf8Chunks { source: self } + } +} + /// An item returned by the [`Utf8Chunks`] iterator. /// /// A `Utf8Chunk` stores a sequence of [`u8`] up to the first broken character @@ -14,15 +54,11 @@ use super::validations::utf8_char_width; /// # Examples /// /// ``` -/// #![feature(utf8_chunks)] -/// -/// use std::str::Utf8Chunks; -/// /// // An invalid UTF-8 string /// let bytes = b"foo\xF1\x80bar"; /// /// // Decode the first `Utf8Chunk` -/// let chunk = Utf8Chunks::new(bytes).next().unwrap(); +/// let chunk = bytes.utf8_chunks().next().unwrap(); /// /// // The first three characters are valid UTF-8 /// assert_eq!("foo", chunk.valid()); @@ -30,7 +66,7 @@ use super::validations::utf8_char_width; /// // The fourth character is broken /// assert_eq!(b"\xF1\x80", chunk.invalid()); /// ``` -#[unstable(feature = "utf8_chunks", issue = "99543")] +#[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] #[derive(Clone, Debug, PartialEq, Eq)] pub struct Utf8Chunk<'a> { valid: &'a str, @@ -43,7 +79,7 @@ impl<'a> Utf8Chunk<'a> { /// This substring can be empty at the start of the string or between /// broken UTF-8 characters. #[must_use] - #[unstable(feature = "utf8_chunks", issue = "99543")] + #[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] pub fn valid(&self) -> &'a str { self.valid } @@ -63,7 +99,7 @@ impl<'a> Utf8Chunk<'a> { /// [`valid`]: Self::valid /// [`U+FFFD REPLACEMENT CHARACTER`]: crate::char::REPLACEMENT_CHARACTER #[must_use] - #[unstable(feature = "utf8_chunks", issue = "99543")] + #[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] pub fn invalid(&self) -> &'a [u8] { self.invalid } @@ -78,7 +114,7 @@ impl fmt::Debug for Debug<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_char('"')?; - for chunk in Utf8Chunks::new(self.0) { + for chunk in self.0.utf8_chunks() { // Valid part. // Here we partially parse UTF-8 again which is suboptimal. { @@ -123,12 +159,8 @@ impl fmt::Debug for Debug<'_> { /// [`String::from_utf8_lossy`] without allocating heap memory: /// /// ``` -/// #![feature(utf8_chunks)] -/// -/// use std::str::Utf8Chunks; -/// /// fn from_utf8_lossy(input: &[u8], mut push: F) where F: FnMut(&str) { -/// for chunk in Utf8Chunks::new(input) { +/// for chunk in input.utf8_chunks() { /// push(chunk.valid()); /// /// if !chunk.invalid().is_empty() { @@ -140,19 +172,13 @@ impl fmt::Debug for Debug<'_> { /// /// [`String::from_utf8_lossy`]: ../../std/string/struct.String.html#method.from_utf8_lossy #[must_use = "iterators are lazy and do nothing unless consumed"] -#[unstable(feature = "utf8_chunks", issue = "99543")] +#[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] #[derive(Clone)] pub struct Utf8Chunks<'a> { source: &'a [u8], } impl<'a> Utf8Chunks<'a> { - /// Creates a new iterator to decode the bytes. - #[unstable(feature = "utf8_chunks", issue = "99543")] - pub fn new(bytes: &'a [u8]) -> Self { - Self { source: bytes } - } - #[doc(hidden)] #[unstable(feature = "str_internals", issue = "none")] pub fn debug(&self) -> Debug<'_> { @@ -160,7 +186,7 @@ impl<'a> Utf8Chunks<'a> { } } -#[unstable(feature = "utf8_chunks", issue = "99543")] +#[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] impl<'a> Iterator for Utf8Chunks<'a> { type Item = Utf8Chunk<'a>; @@ -259,10 +285,10 @@ impl<'a> Iterator for Utf8Chunks<'a> { } } -#[unstable(feature = "utf8_chunks", issue = "99543")] +#[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] impl FusedIterator for Utf8Chunks<'_> {} -#[unstable(feature = "utf8_chunks", issue = "99543")] +#[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] impl fmt::Debug for Utf8Chunks<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("Utf8Chunks").field("source", &self.debug()).finish() diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 61a604561458..3313da9dce78 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -24,7 +24,7 @@ use crate::slice::{self, SliceIndex}; pub mod pattern; mod lossy; -#[unstable(feature = "utf8_chunks", issue = "99543")] +#[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] pub use lossy::{Utf8Chunk, Utf8Chunks}; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index e741149e7ce2..8bbd1901df34 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -118,7 +118,6 @@ #![feature(error_generic_member_access)] #![feature(error_in_core)] #![feature(trait_upcasting)] -#![feature(utf8_chunks)] #![feature(is_ascii_octdigit)] #![feature(get_many_mut)] #![feature(iter_map_windows)] diff --git a/library/core/tests/str_lossy.rs b/library/core/tests/str_lossy.rs index 9d3f0b65fdb9..6e70ea3e2857 100644 --- a/library/core/tests/str_lossy.rs +++ b/library/core/tests/str_lossy.rs @@ -1,10 +1,8 @@ -use core::str::Utf8Chunks; - #[test] fn chunks() { macro_rules! assert_chunks { ( $string:expr, $(($valid:expr, $invalid:expr)),* $(,)? ) => {{ - let mut iter = Utf8Chunks::new($string); + let mut iter = $string.utf8_chunks(); $( let chunk = iter.next().expect("missing chunk"); assert_eq!($valid, chunk.valid()); @@ -79,7 +77,7 @@ fn debug() { "\"Hello\\xC0\\x80 There\\xE6\\x83 Goodbye\\u{10d4ea}\"", &format!( "{:?}", - Utf8Chunks::new(b"Hello\xC0\x80 There\xE6\x83 Goodbye\xf4\x8d\x93\xaa").debug(), + b"Hello\xC0\x80 There\xE6\x83 Goodbye\xf4\x8d\x93\xaa".utf8_chunks().debug(), ), ); } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index e9de3b776704..906b64c0dd28 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -313,7 +313,6 @@ #![feature(thread_local)] #![feature(try_blocks)] #![feature(type_alias_impl_trait)] -#![feature(utf8_chunks)] // tidy-alphabetical-end // // Library features (core): diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs index 4ca3f1cd1853..9be02bc191e5 100644 --- a/library/std/src/sys/os_str/bytes.rs +++ b/library/std/src/sys/os_str/bytes.rs @@ -11,8 +11,6 @@ use crate::str; use crate::sync::Arc; use crate::sys_common::{AsInner, IntoInner}; -use core::str::Utf8Chunks; - #[cfg(test)] mod tests; @@ -29,7 +27,7 @@ pub struct Slice { impl fmt::Debug for Slice { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&Utf8Chunks::new(&self.inner).debug(), f) + fmt::Debug::fmt(&self.inner.utf8_chunks().debug(), f) } } @@ -41,7 +39,7 @@ impl fmt::Display for Slice { return "".fmt(f); } - for chunk in Utf8Chunks::new(&self.inner) { + for chunk in self.inner.utf8_chunks() { let valid = chunk.valid(); // If we successfully decoded the whole chunk as a valid string then // we can return a direct formatting of the string which will also From 32aadc516bb2dad9913d2600da5dd1d4478e552f Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 24 Apr 2024 16:47:47 -0700 Subject: [PATCH 046/279] bootstrap: link to the forge about toolstate --- src/bootstrap/src/core/build_steps/toolstate.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/toolstate.rs b/src/bootstrap/src/core/build_steps/toolstate.rs index 6065aa1414fe..c123bc764ffe 100644 --- a/src/bootstrap/src/core/build_steps/toolstate.rs +++ b/src/bootstrap/src/core/build_steps/toolstate.rs @@ -1,6 +1,8 @@ -//! Toolstate checks to keep tools building +//! [Toolstate] checks to keep tools building //! //! Reachable via `./x.py test` but mostly relevant for CI, since it isn't run locally by default. +//! +//! [Toolstate]: https://forge.rust-lang.org/infra/toolstate.html use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::utils::helpers::t; From f4e02a193e39958df1cee6abeefc62e50354fdea Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 24 Apr 2024 16:56:41 -0700 Subject: [PATCH 047/279] bootstrap: reinterpret the main advantage of x.py setup --- src/bootstrap/src/core/build_steps/setup.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index a01d20e8c21a..620094145802 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -1,8 +1,9 @@ //! First time setup of a dev environment //! //! These are build-and-run steps for `./x.py setup`, which allows quickly setting up the directory -//! for modifying, building, and running the compiler and library. The main convenience is to allow -//! not having to painstakingly set every single option in config.toml. +//! for modifying, building, and running the compiler and library. Running arbitrary configuration +//! allows setting up things that cannot be simply captured inside the config.toml, in addition to +//! leading people away from manually editing most of the config.toml values. use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::t; From 11e95d43ae826212080aa8911a188d9a908bf532 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 25 Apr 2024 15:16:10 +1000 Subject: [PATCH 048/279] Name the field in `Expander`. For code clarity. --- compiler/rustc_builtin_macros/src/derive.rs | 6 ++++-- compiler/rustc_builtin_macros/src/lib.rs | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index 4f412cf79d91..ca03941f9509 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -10,7 +10,9 @@ use rustc_session::Session; use rustc_span::symbol::{sym, Ident}; use rustc_span::{ErrorGuaranteed, Span}; -pub(crate) struct Expander(pub bool); +pub(crate) struct Expander { + pub is_const: bool, +} impl MultiItemModifier for Expander { fn expand( @@ -58,7 +60,7 @@ impl MultiItemModifier for Expander { report_path_args(sess, meta); meta.path.clone() }) - .map(|path| (path, dummy_annotatable(), None, self.0)) + .map(|path| (path, dummy_annotatable(), None, self.is_const)) .collect() } _ => vec![], diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 1b4c6041294f..56a72432689d 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -109,8 +109,8 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { bench: test::expand_bench, cfg_accessible: cfg_accessible::Expander, cfg_eval: cfg_eval::expand, - derive: derive::Expander(false), - derive_const: derive::Expander(true), + derive: derive::Expander { is_const: false }, + derive_const: derive::Expander { is_const: true }, global_allocator: global_allocator::expand, test: test::expand_test, test_case: test::expand_test_case, From 144bdf5bf1a722fc73f8bd24fa05c5cbb2845701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 23 Apr 2024 15:16:21 +0200 Subject: [PATCH 049/279] Remove `master` CI job --- .github/workflows/ci.yml | 31 +++++-------------------------- src/ci/github-actions/ci.yml | 28 +++++++++------------------- 2 files changed, 14 insertions(+), 45 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3651ef2c614e..765dffaaff5e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -152,30 +152,6 @@ jobs: AWS_ACCESS_KEY_ID: "${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }}" AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }}" if: "success() && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')" - master: - name: master - runs-on: ubuntu-latest - env: - SCCACHE_BUCKET: rust-lang-ci-sccache2 - DEPLOY_BUCKET: rust-lang-ci2 - TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate" - TOOLSTATE_ISSUES_API_URL: "https://api.github.com/repos/rust-lang/rust/issues" - TOOLSTATE_PUBLISH: 1 - CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL - ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55 - AWS_REGION: us-west-1 - CACHE_DOMAIN: ci-caches.rust-lang.org - if: "github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'rust-lang-ci/rust'" - steps: - - name: checkout the source code - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - name: publish toolstate - run: src/ci/publish_toolstate.sh - shell: bash - env: - TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}" try-success: needs: - job @@ -201,9 +177,12 @@ jobs: - job if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" steps: - - name: mark the job as a success - run: exit 0 + - name: publish toolstate + run: src/ci/publish_toolstate.sh shell: bash + if: "success() && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')" + env: + TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}" name: bors build finished runs-on: ubuntu-latest auto-failure: diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index bc4b1b815cf3..081e5ed21e09 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -351,24 +351,6 @@ jobs: # This hack is taken from https://github.com/ferrocene/ferrocene/blob/d43edc6b7697cf1719ec1c17c54904ab94825763/.github/workflows/release.yml#L75-L82 if: fromJSON(needs.calculate_matrix.outputs.jobs)[0] != null - master: - name: master - runs-on: ubuntu-latest - env: - <<: [*prod-variables] - if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'rust-lang-ci/rust' - steps: - - name: checkout the source code - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - - name: publish toolstate - run: src/ci/publish_toolstate.sh - shell: bash - env: - TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }} - # These jobs don't actually test anything, but they're used to tell bors the # build completed, as there is no practical way to detect when a workflow is # successful listening to webhooks only. @@ -383,7 +365,15 @@ jobs: auto-success: needs: [ job ] if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" - <<: *base-success-job + <<: *base-outcome-job + steps: + - name: publish toolstate + run: src/ci/publish_toolstate.sh + shell: bash + if: success() && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1') + env: + TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }} + auto-failure: needs: [ job ] if: "!success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" From 744dc2aa1d59c09a5cf3de5c4985dd914756219a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 24 Apr 2024 15:00:42 +0200 Subject: [PATCH 050/279] Inline `base-ci-job` YAML anchor and remove unused anchors --- .github/workflows/ci.yml | 10 +- src/ci/github-actions/ci.yml | 258 ++++++++++++----------------------- 2 files changed, 93 insertions(+), 175 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 765dffaaff5e..477f521d3b4d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,6 +51,11 @@ jobs: name: "${{ matrix.name }}" needs: - calculate_matrix + runs-on: "${{ matrix.os }}" + defaults: + run: + shell: "${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}" + timeout-minutes: 600 env: CI_JOB_NAME: "${{ matrix.image }}" CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse @@ -64,11 +69,6 @@ jobs: matrix: include: "${{ fromJSON(needs.calculate_matrix.outputs.jobs) }}" if: "fromJSON(needs.calculate_matrix.outputs.jobs)[0] != null" - defaults: - run: - shell: "${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}" - timeout-minutes: 600 - runs-on: "${{ matrix.os }}" steps: - if: "contains(matrix.os, 'windows')" uses: msys2/setup-msys2@v2.22.0 diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 081e5ed21e09..e27969948514 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -29,91 +29,107 @@ # The expand-yaml-anchors tool will automatically remove this block from the # output YAML file. x--expand-yaml-anchors--remove: - - &shared-ci-variables - CI_JOB_NAME: ${{ matrix.name }} - CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - # commit of PR sha or commit sha. `GITHUB_SHA` is not accurate for PRs. - HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} - DOCKER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # These snippets are used by the try-success, try-failure, auto-success and auto-failure jobs. + # Check out their documentation for more information on why they're needed. - - &public-variables - SCCACHE_BUCKET: rust-lang-ci-sccache2 - TOOLSTATE_REPO: https://github.com/rust-lang-nursery/rust-toolstate - CACHE_DOMAIN: ci-caches.rust-lang.org + - &base-outcome-job + name: bors build finished + runs-on: ubuntu-latest - - &prod-variables - SCCACHE_BUCKET: rust-lang-ci-sccache2 - DEPLOY_BUCKET: rust-lang-ci2 - TOOLSTATE_REPO: https://github.com/rust-lang-nursery/rust-toolstate - TOOLSTATE_ISSUES_API_URL: https://api.github.com/repos/rust-lang/rust/issues - TOOLSTATE_PUBLISH: 1 - # AWS_SECRET_ACCESS_KEYs are stored in GitHub's secrets storage, named - # AWS_SECRET_ACCESS_KEY_. Including the key id in the name allows to - # rotate them in a single branch while keeping the old key in another - # branch, which wouldn't be possible if the key was named with the kind - # (caches, artifacts...). - CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL - ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55 - AWS_REGION: us-west-1 - CACHE_DOMAIN: ci-caches.rust-lang.org + - &base-success-job + steps: + - name: mark the job as a success + run: exit 0 + shell: bash + <<: *base-outcome-job - - &dummy-variables - SCCACHE_BUCKET: rust-lang-gha-caches - DEPLOY_BUCKET: rust-lang-gha - TOOLSTATE_REPO: https://github.com/pietroalbini/rust-toolstate - TOOLSTATE_ISSUES_API_URL: https://api.github.com/repos/pietroalbini/rust-toolstate/issues - TOOLSTATE_PUBLISH: 1 - # AWS_SECRET_ACCESS_KEYs are stored in GitHub's secrets storage, named - # AWS_SECRET_ACCESS_KEY_. Including the key id in the name allows to - # rotate them in a single branch while keeping the old key in another - # branch, which wouldn't be possible if the key was named with the kind - # (caches, artifacts...). - CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZOMUQATD5 - ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZH5AYXDVF - AWS_REGION: us-west-1 - CACHE_DOMAIN: ci-caches-gha.rust-lang.org + - &base-failure-job + steps: + - name: mark the job as a failure + run: exit 1 + shell: bash + <<: *base-outcome-job - - &base-job - env: {} +########################### +# Builders definition # +########################### - - &job-linux-4c - os: ubuntu-20.04-4core-16gb - <<: *base-job +name: CI +on: + push: + branches: + - auto + - try + - try-perf + - automation/bors/try + - master + pull_request: + branches: + - "**" - - &job-linux-8c - os: ubuntu-20.04-8core-32gb - <<: *base-job +permissions: + contents: read + packages: write - - &job-linux-16c - os: ubuntu-20.04-16core-64gb - <<: *base-job +defaults: + run: + # On Linux, macOS, and Windows, use the system-provided bash as the default + # shell. (This should only make a difference on Windows, where the default + # shell is PowerShell.) + shell: bash - - &job-macos-xl - os: macos-13 # We use the standard runner for now - <<: *base-job +concurrency: + # For a given workflow, if we push to the same branch, cancel all previous builds on that branch. + # We add an exception for try builds (try branch) and unrolled rollup builds (try-perf), which + # are all triggered on the same branch, but which should be able to run concurrently. + group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }} + cancel-in-progress: true - - &job-macos-m1 - os: macos-14 - <<: *base-job - - - &job-windows-8c - os: windows-2019-8core-32gb - <<: *base-job - - - &job-windows-16c - os: windows-2019-16core-64gb - <<: *base-job - - - &job-aarch64-linux - os: [self-hosted, ARM64, linux] - - - &base-ci-job +jobs: + # The job matrix for `calculate_matrix` is defined in src/ci/github-actions/jobs.yml. + # It calculates which jobs should be executed, based on the data of the ${{ github }} context. + # If you want to modify CI jobs, take a look at src/ci/github-actions/jobs.yml. + calculate_matrix: + name: Calculate job matrix + runs-on: ubuntu-latest + outputs: + jobs: ${{ steps.jobs.outputs.jobs }} + steps: + - name: Checkout the source code + uses: actions/checkout@v4 + - name: Calculate the CI job matrix + run: python3 src/ci/github-actions/calculate-job-matrix.py >> $GITHUB_OUTPUT + id: jobs + job: + name: ${{ matrix.name }} + needs: [ calculate_matrix ] + runs-on: "${{ matrix.os }}" defaults: run: shell: ${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }} timeout-minutes: 600 - runs-on: "${{ matrix.os }}" - env: *shared-ci-variables + env: + CI_JOB_NAME: ${{ matrix.image }} + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + # commit of PR sha or commit sha. `GITHUB_SHA` is not accurate for PRs. + HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} + DOCKER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SCCACHE_BUCKET: rust-lang-ci-sccache2 + TOOLSTATE_REPO: https://github.com/rust-lang-nursery/rust-toolstate + CACHE_DOMAIN: ci-caches.rust-lang.org + continue-on-error: ${{ matrix.continue_on_error || false }} + strategy: + matrix: + # Check the `calculate_matrix` job to see how is the matrix defined. + include: ${{ fromJSON(needs.calculate_matrix.outputs.jobs) }} + # GitHub Actions fails the workflow if an empty list of jobs is provided to + # the workflow, so we need to skip this job if nothing was produced by + # the Python script. + # + # Unfortunately checking whether a list is empty is not possible in a nice + # way due to GitHub Actions expressions limits. + # This hack is taken from https://github.com/ferrocene/ferrocene/blob/d43edc6b7697cf1719ec1c17c54904ab94825763/.github/workflows/release.yml#L75-L82 + if: fromJSON(needs.calculate_matrix.outputs.jobs)[0] != null steps: - if: contains(matrix.os, 'windows') uses: msys2/setup-msys2@v2.22.0 @@ -253,104 +269,6 @@ x--expand-yaml-anchors--remove: # erroring about invalid credentials instead. if: success() && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1') - # These snippets are used by the try-success, try-failure, auto-success and auto-failure jobs. - # Check out their documentation for more information on why they're needed. - - - &base-outcome-job - name: bors build finished - runs-on: ubuntu-latest - - - &base-success-job - steps: - - name: mark the job as a success - run: exit 0 - shell: bash - <<: *base-outcome-job - - - &base-failure-job - steps: - - name: mark the job as a failure - run: exit 1 - shell: bash - <<: *base-outcome-job - -########################### -# Builders definition # -########################### - -name: CI -on: - push: - branches: - - auto - - try - - try-perf - - automation/bors/try - - master - pull_request: - branches: - - "**" - -permissions: - contents: read - packages: write - -defaults: - run: - # On Linux, macOS, and Windows, use the system-provided bash as the default - # shell. (This should only make a difference on Windows, where the default - # shell is PowerShell.) - shell: bash - -concurrency: - # For a given workflow, if we push to the same branch, cancel all previous builds on that branch. - # We add an exception for try builds (try branch) and unrolled rollup builds (try-perf), which - # are all triggered on the same branch, but which should be able to run concurrently. - group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }} - cancel-in-progress: true - -jobs: - # The job matrix for `calculate_matrix` is defined in src/ci/github-actions/jobs.yml. - # It calculates which jobs should be executed, based on the data of the ${{ github }} context. - # If you want to modify CI jobs, take a look at src/ci/github-actions/jobs.yml. - calculate_matrix: - name: Calculate job matrix - runs-on: ubuntu-latest - outputs: - jobs: ${{ steps.jobs.outputs.jobs }} - steps: - - name: Checkout the source code - uses: actions/checkout@v4 - - name: Calculate the CI job matrix - run: python3 src/ci/github-actions/calculate-job-matrix.py >> $GITHUB_OUTPUT - id: jobs - job: - <<: *base-ci-job - name: ${{ matrix.name }} - needs: [ calculate_matrix ] - env: - CI_JOB_NAME: ${{ matrix.image }} - CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - # commit of PR sha or commit sha. `GITHUB_SHA` is not accurate for PRs. - HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} - DOCKER_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SCCACHE_BUCKET: rust-lang-ci-sccache2 - TOOLSTATE_REPO: https://github.com/rust-lang-nursery/rust-toolstate - CACHE_DOMAIN: ci-caches.rust-lang.org - continue-on-error: ${{ matrix.continue_on_error || false }} - strategy: - matrix: - # Check the `calculate_matrix` job to see how is the matrix defined. - include: ${{ fromJSON(needs.calculate_matrix.outputs.jobs) }} - # GitHub Actions fails the workflow if an empty list of jobs is provided to - # the workflow, so we need to skip this job if nothing was produced by - # the Python script. - # - # Unfortunately checking whether a list is empty is not possible in a nice - # way due to GitHub Actions expressions limits. - # This hack is taken from https://github.com/ferrocene/ferrocene/blob/d43edc6b7697cf1719ec1c17c54904ab94825763/.github/workflows/release.yml#L75-L82 - if: fromJSON(needs.calculate_matrix.outputs.jobs)[0] != null - # These jobs don't actually test anything, but they're used to tell bors the # build completed, as there is no practical way to detect when a workflow is # successful listening to webhooks only. From 86da0e758faaf46a8025660a815a673ebafa1933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 25 Apr 2024 10:47:10 +0200 Subject: [PATCH 051/279] Remove useless condition Neither `env.DEPLOY` nor `env.DEPLOY_ALT` should be present in this job. --- .github/workflows/ci.yml | 1 - src/ci/github-actions/ci.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 477f521d3b4d..32bfc7170b9a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -180,7 +180,6 @@ jobs: - name: publish toolstate run: src/ci/publish_toolstate.sh shell: bash - if: "success() && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')" env: TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}" name: bors build finished diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index e27969948514..0439b053fda1 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -288,7 +288,6 @@ jobs: - name: publish toolstate run: src/ci/publish_toolstate.sh shell: bash - if: success() && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1') env: TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }} From e82c28debc2762055bf2ddecba9627facdb21c74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 25 Apr 2024 11:06:27 +0200 Subject: [PATCH 052/279] Remove `master` push hook --- .github/workflows/ci.yml | 1 - src/ci/github-actions/ci.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 32bfc7170b9a..231bb971713f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,6 @@ name: CI - try - try-perf - automation/bors/try - - master pull_request: branches: - "**" diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 0439b053fda1..98b27950fbb0 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -62,7 +62,6 @@ on: - try - try-perf - automation/bors/try - - master pull_request: branches: - "**" From b52e4bd99709fdf3c9b709f285d0ab4278fbcf8f Mon Sep 17 00:00:00 2001 From: Lieselotte <52315535+she3py@users.noreply.github.com> Date: Thu, 25 Apr 2024 13:09:13 +0200 Subject: [PATCH 053/279] Fix substitution parts having a shifted underline in some cases --- compiler/rustc_errors/src/emitter.rs | 4 ++-- tests/ui/parser/issues/issue-32505.stderr | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 6ce3fa3535dc..6074a4a30bbd 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2019,7 +2019,7 @@ impl HumanEmitter { let offset: isize = offsets .iter() .filter_map( - |(start, v)| if span_start_pos <= *start { None } else { Some(v) }, + |(start, v)| if span_start_pos < *start { None } else { Some(v) }, ) .sum(); let underline_start = (span_start_pos + start) as isize + offset; @@ -2028,7 +2028,7 @@ impl HumanEmitter { let padding: usize = max_line_num_len + 3; for p in underline_start..underline_end { if let DisplaySuggestion::Underline = show_code_change { - // If this is a replacement, underline with `^`, if this is an addition + // If this is a replacement, underline with `~`, if this is an addition // underline with `+`. buffer.putc( row_num, diff --git a/tests/ui/parser/issues/issue-32505.stderr b/tests/ui/parser/issues/issue-32505.stderr index 27ad2c3e5be1..0eaa5efd525f 100644 --- a/tests/ui/parser/issues/issue-32505.stderr +++ b/tests/ui/parser/issues/issue-32505.stderr @@ -9,7 +9,7 @@ LL | foo(|_|) help: you might have meant to open the body of the closure | LL | foo(|_| {}) - | ++ + | ++ error[E0425]: cannot find function `foo` in this scope --> $DIR/issue-32505.rs:2:5 From 2293f1ed6ad693c57938a5e29fbb0c7066f61860 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 12 Mar 2024 13:51:46 +0100 Subject: [PATCH 054/279] `obligations_for_self_ty` to sub module --- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 59 ----------------- .../src/fn_ctxt/inspect_obligations.rs | 64 +++++++++++++++++++ compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 1 + 3 files changed, 65 insertions(+), 59 deletions(-) create mode 100644 compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 0ba5d187864f..61e3ac248026 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -3,7 +3,6 @@ use crate::errors::CtorIsPrivate; use crate::method::{self, MethodCallee, SelfSource}; use crate::rvalue_scopes; use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy}; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey}; use rustc_hir as hir; @@ -636,64 +635,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ret_ty.builtin_deref(true).unwrap() } - #[instrument(skip(self), level = "debug")] - fn self_type_matches_expected_vid(&self, self_ty: Ty<'tcx>, expected_vid: ty::TyVid) -> bool { - let self_ty = self.shallow_resolve(self_ty); - debug!(?self_ty); - - match *self_ty.kind() { - ty::Infer(ty::TyVar(found_vid)) => { - let found_vid = self.root_var(found_vid); - debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid); - expected_vid == found_vid - } - _ => false, - } - } - - #[instrument(skip(self), level = "debug")] - pub(in super::super) fn obligations_for_self_ty<'b>( - &'b self, - self_ty: ty::TyVid, - ) -> impl DoubleEndedIterator> + Captures<'tcx> + 'b - { - let ty_var_root = self.root_var(self_ty); - trace!("pending_obligations = {:#?}", self.fulfillment_cx.borrow().pending_obligations()); - - self.fulfillment_cx.borrow().pending_obligations().into_iter().filter_map( - move |obligation| match &obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) - if self.self_type_matches_expected_vid( - data.projection_ty.self_ty(), - ty_var_root, - ) => - { - Some(obligation) - } - ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) - if self.self_type_matches_expected_vid(data.self_ty(), ty_var_root) => - { - Some(obligation) - } - - ty::PredicateKind::Clause(ty::ClauseKind::Trait(..)) - | ty::PredicateKind::Clause(ty::ClauseKind::Projection(..)) - | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) - | ty::PredicateKind::Subtype(..) - | ty::PredicateKind::Coerce(..) - | ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..)) - | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..)) - | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..)) - | ty::PredicateKind::ObjectSafe(..) - | ty::PredicateKind::NormalizesTo(..) - | ty::PredicateKind::AliasRelate(..) - | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) - | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::Ambiguous => None, - }, - ) - } - pub(in super::super) fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool { let sized_did = self.tcx.lang_items().sized_trait(); self.obligations_for_self_ty(self_ty).any(|obligation| { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs new file mode 100644 index 000000000000..14d6c3aaaa6c --- /dev/null +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs @@ -0,0 +1,64 @@ +use crate::FnCtxt; +use rustc_middle::ty::{self, Ty}; +use rustc_infer::traits; +use rustc_data_structures::captures::Captures; + +impl<'a, 'tcx> FnCtxt<'a, 'tcx> { + #[instrument(skip(self), level = "debug")] + pub(crate) fn obligations_for_self_ty<'b>( + &'b self, + self_ty: ty::TyVid, + ) -> impl DoubleEndedIterator> + Captures<'tcx> + 'b + { + let ty_var_root = self.root_var(self_ty); + trace!("pending_obligations = {:#?}", self.fulfillment_cx.borrow().pending_obligations()); + + self.fulfillment_cx.borrow().pending_obligations().into_iter().filter_map( + move |obligation| match &obligation.predicate.kind().skip_binder() { + ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) + if self.self_type_matches_expected_vid( + data.projection_ty.self_ty(), + ty_var_root, + ) => + { + Some(obligation) + } + ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) + if self.self_type_matches_expected_vid(data.self_ty(), ty_var_root) => + { + Some(obligation) + } + + ty::PredicateKind::Clause(ty::ClauseKind::Trait(..)) + | ty::PredicateKind::Clause(ty::ClauseKind::Projection(..)) + | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) + | ty::PredicateKind::Subtype(..) + | ty::PredicateKind::Coerce(..) + | ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..)) + | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..)) + | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..)) + | ty::PredicateKind::ObjectSafe(..) + | ty::PredicateKind::NormalizesTo(..) + | ty::PredicateKind::AliasRelate(..) + | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) + | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous => None, + }, + ) + } + + #[instrument(level = "debug", skip(self), ret)] + fn self_type_matches_expected_vid(&self, self_ty: Ty<'tcx>, expected_vid: ty::TyVid) -> bool { + let self_ty = self.shallow_resolve(self_ty); + debug!(?self_ty); + + match *self_ty.kind() { + ty::Infer(ty::TyVar(found_vid)) => { + let found_vid = self.root_var(found_vid); + debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid); + expected_vid == found_vid + } + _ => false, + } + } +} \ No newline at end of file diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 080571e1a708..2f96cf9e373c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -2,6 +2,7 @@ mod _impl; mod adjust_fulfillment_errors; mod arg_matrix; mod checks; +mod inspect_obligations; mod suggestions; use crate::coercion::DynamicCoerceMany; From 662eadbafb4d4021eb0f0cbe0b2521f2e3da3531 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 12 Mar 2024 13:56:12 +0100 Subject: [PATCH 055/279] `pub(in super::super)` to `pub(crate)` `super::super` of `rustc_hir_typeck::fn_ctxt::_impl` is just `rustc_hir_typeck`. --- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 61e3ac248026..73fdcddf0492 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -46,7 +46,7 @@ use std::slice; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Produces warning on the given node, if the current point in the /// function is unreachable, and there hasn't been another warning. - pub(in super::super) fn warn_if_unreachable(&self, id: HirId, span: Span, kind: &str) { + pub(crate) fn warn_if_unreachable(&self, id: HirId, span: Span, kind: &str) { // FIXME: Combine these two 'if' expressions into one once // let chains are implemented if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() { @@ -86,7 +86,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // FIXME(-Znext-solver): A lot of the calls to this method should // probably be `try_structurally_resolve_type` or `structurally_resolve_type` instead. #[instrument(skip(self), level = "debug", ret)] - pub(in super::super) fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> { + pub(crate) fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> { // No Infer()? Nothing needs doing. if !ty.has_non_region_infer() { debug!("no inference var, nothing needs doing"); @@ -108,7 +108,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.resolve_vars_if_possible(ty) } - pub(in super::super) fn record_deferred_call_resolution( + pub(crate) fn record_deferred_call_resolution( &self, closure_def_id: LocalDefId, r: DeferredCallResolution<'tcx>, @@ -117,7 +117,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { deferred_call_resolutions.entry(closure_def_id).or_default().push(r); } - pub(in super::super) fn remove_deferred_call_resolutions( + pub(crate) fn remove_deferred_call_resolutions( &self, closure_def_id: LocalDefId, ) -> Vec> { @@ -171,7 +171,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } #[instrument(level = "debug", skip(self))] - pub(in super::super) fn write_resolution( + pub(crate) fn write_resolution( &self, hir_id: HirId, r: Result<(DefKind, DefId), ErrorGuaranteed>, @@ -335,7 +335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Instantiates and normalizes the bounds for a given item - pub(in super::super) fn instantiate_bounds( + pub(crate) fn instantiate_bounds( &self, span: Span, def_id: DefId, @@ -348,7 +348,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { result } - pub(in super::super) fn normalize(&self, span: Span, value: T) -> T + pub(crate) fn normalize(&self, span: Span, value: T) -> T where T: TypeFoldable>, { @@ -536,7 +536,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.normalize(span, field.ty(self.tcx, args)) } - pub(in super::super) fn resolve_rvalue_scopes(&self, def_id: DefId) { + pub(crate) fn resolve_rvalue_scopes(&self, def_id: DefId) { let scope_tree = self.tcx.region_scope_tree(def_id); let rvalue_scopes = { rvalue_scopes::resolve_rvalue_scopes(self, scope_tree, def_id) }; let mut typeck_results = self.typeck_results.borrow_mut(); @@ -552,7 +552,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// We must not attempt to select obligations after this method has run, or risk query cycle /// ICE. #[instrument(level = "debug", skip(self))] - pub(in super::super) fn resolve_coroutine_interiors(&self) { + pub(crate) fn resolve_coroutine_interiors(&self) { // Try selecting all obligations that are not blocked on inference variables. // Once we start unifying coroutine witnesses, trying to select obligations on them will // trigger query cycle ICEs, as doing so requires MIR. @@ -593,7 +593,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } #[instrument(skip(self), level = "debug")] - pub(in super::super) fn report_ambiguity_errors(&self) { + pub(crate) fn report_ambiguity_errors(&self) { let mut errors = self.fulfillment_cx.borrow_mut().collect_remaining_errors(self); if !errors.is_empty() { @@ -608,7 +608,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Select as many obligations as we can at present. - pub(in super::super) fn select_obligations_where_possible( + pub(crate) fn select_obligations_where_possible( &self, mutate_fulfillment_errors: impl Fn(&mut Vec>), ) { @@ -624,7 +624,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// returns a type of `&T`, but the actual type we assign to the /// *expression* is `T`. So this function just peels off the return /// type by one layer to yield `T`. - pub(in super::super) fn make_overloaded_place_return_type( + pub(crate) fn make_overloaded_place_return_type( &self, method: MethodCallee<'tcx>, ) -> ty::TypeAndMut<'tcx> { @@ -635,7 +635,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ret_ty.builtin_deref(true).unwrap() } - pub(in super::super) fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool { + pub(crate) fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool { let sized_did = self.tcx.lang_items().sized_trait(); self.obligations_for_self_ty(self_ty).any(|obligation| { match obligation.predicate.kind().skip_binder() { @@ -647,7 +647,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) } - pub(in super::super) fn err_args(&self, len: usize) -> Vec> { + pub(crate) fn err_args(&self, len: usize) -> Vec> { let ty_error = Ty::new_misc_error(self.tcx); vec![ty_error; len] } @@ -655,7 +655,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Unifies the output type with the expected type early, for more coercions /// and forward type information on the input expressions. #[instrument(skip(self, call_span), level = "debug")] - pub(in super::super) fn expected_inputs_for_expected_output( + pub(crate) fn expected_inputs_for_expected_output( &self, call_span: Span, expected_ret: Expectation<'tcx>, @@ -688,7 +688,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expect_args } - pub(in super::super) fn resolve_lang_item_path( + pub(crate) fn resolve_lang_item_path( &self, lang_item: hir::LangItem, span: Span, @@ -867,7 +867,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// but we often want access to the parent function's signature. /// /// Otherwise, return false. - pub(in super::super) fn get_node_fn_decl( + pub(crate) fn get_node_fn_decl( &self, node: Node<'tcx>, ) -> Option<(LocalDefId, &'tcx hir::FnDecl<'tcx>, Ident, bool)> { @@ -945,7 +945,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) } - pub(in super::super) fn note_internal_mutation_in_method( + pub(crate) fn note_internal_mutation_in_method( &self, err: &mut Diag<'_>, expr: &hir::Expr<'_>, @@ -1490,7 +1490,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub(in super::super) fn with_breakable_ctxt R, R>( + pub(crate) fn with_breakable_ctxt R, R>( &self, id: HirId, ctxt: BreakableCtxt<'tcx>, @@ -1516,7 +1516,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Instantiate a QueryResponse in a probe context, without a /// good ObligationCause. - pub(in super::super) fn probe_instantiate_query_response( + pub(crate) fn probe_instantiate_query_response( &self, span: Span, original_values: &OriginalQueryValues<'tcx>, @@ -1531,7 +1531,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Returns `true` if an expression is contained inside the LHS of an assignment expression. - pub(in super::super) fn expr_in_place(&self, mut expr_id: HirId) -> bool { + pub(crate) fn expr_in_place(&self, mut expr_id: HirId) -> bool { let mut contained_in_place = false; while let hir::Node::Expr(parent_expr) = self.tcx.parent_hir_node(expr_id) { From 538ddb0ac2a3f15ac43bd0444b36b755354f525e Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Thu, 25 Apr 2024 11:05:01 -0700 Subject: [PATCH 056/279] thread_local: use less &mut T in LazyKeyInner::take Instead, use raw pointers to accomplish internal mutability throughout. --- library/std/src/sys/thread_local/mod.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index 8b2c839f837d..4fcea052ed0a 100644 --- a/library/std/src/sys/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs @@ -91,13 +91,15 @@ mod lazy { } } - /// The other methods hand out references while taking &self. - /// As such, callers of this method must ensure no `&` and `&mut` are - /// available and used at the same time. + /// Watch out: unsynchronized internal mutability! + /// + /// # Safety + /// Unsound if called while any `&'static T` is active. #[allow(unused)] - pub unsafe fn take(&mut self) -> Option { - // SAFETY: See doc comment for this method. - unsafe { (*self.inner.get()).take() } + pub(crate) unsafe fn take(&self) -> Option { + let mutable: *mut _ = UnsafeCell::get(&self.inner); + // SAFETY: That's the caller's problem. + unsafe { mutable.replace(None) } } } } From 03878c682a68dc2891eccbd04b5d2f04c91ba0c4 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 12 Mar 2024 14:26:30 +0100 Subject: [PATCH 057/279] hir typeck: look into nested goals uses a `ProofTreeVisitor` to look into nested goals when looking at the pending obligations during hir typeck. Used by closure signature inference, coercion, and for async functions. --- compiler/rustc_hir_typeck/src/closure.rs | 6 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- .../src/fn_ctxt/inspect_obligations.rs | 174 +++++++---- .../rustc_middle/src/traits/solve/inspect.rs | 1 + .../src/solve/assembly/mod.rs | 26 +- .../src/solve/eval_ctxt/canonical.rs | 103 ++++--- .../src/solve/eval_ctxt/mod.rs | 52 ++-- .../src/solve/eval_ctxt/probe.rs | 18 +- .../src/solve/inspect/analyse.rs | 179 ++++++++---- .../src/solve/inspect/build.rs | 273 +++++++++++------- .../rustc_trait_selection/src/solve/mod.rs | 12 - .../src/traits/coherence.rs | 10 +- src/tools/tidy/src/issues.txt | 1 - .../deduce-from-opaque-type-after-norm.rs | 11 + .../deduce-from-opaque-type.rs | 9 + .../infer-higher-ranked-signature.rs | 20 ++ .../infer-signature-from-impl.rs | 3 +- ...n-with-leaking-placeholders.current.stderr | 15 + ...ion-with-leaking-placeholders.next.stderr} | 3 +- .../obligation-with-leaking-placeholders.rs | 23 ++ ...rtrait-signature-inference-issue-23012.rs} | 3 + ...e-closure-signature-after-normalization.rs | 11 - ...osure-signature-after-normalization.stderr | 14 - 23 files changed, 642 insertions(+), 327 deletions(-) create mode 100644 tests/ui/closures/deduce-signature/deduce-from-opaque-type-after-norm.rs create mode 100644 tests/ui/closures/deduce-signature/deduce-from-opaque-type.rs create mode 100644 tests/ui/closures/deduce-signature/infer-higher-ranked-signature.rs rename tests/ui/closures/{ => deduce-signature}/infer-signature-from-impl.rs (79%) create mode 100644 tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.current.stderr rename tests/ui/closures/{infer-signature-from-impl.next.stderr => deduce-signature/obligation-with-leaking-placeholders.next.stderr} (87%) create mode 100644 tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.rs rename tests/ui/closures/{issue-23012-supertrait-signature-inference.rs => deduce-signature/supertrait-signature-inference-issue-23012.rs} (84%) delete mode 100644 tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs delete mode 100644 tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.stderr diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index d6704d9e44f9..4883c7aff8bc 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -342,7 +342,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Infer(ty::TyVar(vid)) => self.deduce_closure_signature_from_predicates( Ty::new_var(self.tcx, self.root_var(vid)), closure_kind, - self.obligations_for_self_ty(vid).map(|obl| (obl.predicate, obl.cause.span)), + self.obligations_for_self_ty(vid) + .into_iter() + .map(|obl| (obl.predicate, obl.cause.span)), ), ty::FnPtr(sig) => match closure_kind { hir::ClosureKind::Closure => { @@ -889,7 +891,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let output_ty = match *ret_ty.kind() { ty::Infer(ty::TyVar(ret_vid)) => { - self.obligations_for_self_ty(ret_vid).find_map(|obligation| { + self.obligations_for_self_ty(ret_vid).into_iter().find_map(|obligation| { get_future_output(obligation.predicate, obligation.cause.span) })? } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 73fdcddf0492..2060e08aacf9 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -637,7 +637,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool { let sized_did = self.tcx.lang_items().sized_trait(); - self.obligations_for_self_ty(self_ty).any(|obligation| { + self.obligations_for_self_ty(self_ty).into_iter().any(|obligation| { match obligation.predicate.kind().skip_binder() { ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => { Some(data.def_id()) == sized_did diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs index 14d6c3aaaa6c..c2068d9f66b8 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs @@ -1,64 +1,140 @@ +//! A utility module to inspect currently ambiguous obligations in the current context. +use crate::rustc_middle::ty::TypeVisitableExt; use crate::FnCtxt; +use rustc_infer::traits::solve::Goal; +use rustc_infer::traits::{self, ObligationCause}; use rustc_middle::ty::{self, Ty}; -use rustc_infer::traits; -use rustc_data_structures::captures::Captures; +use rustc_span::Span; +use rustc_trait_selection::solve::inspect::ProofTreeInferCtxtExt; +use rustc_trait_selection::solve::inspect::{InspectConfig, InspectGoal, ProofTreeVisitor}; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { + /// Returns a list of all obligations whose self type has been unified + /// with the unconstrained type `self_ty`. #[instrument(skip(self), level = "debug")] - pub(crate) fn obligations_for_self_ty<'b>( - &'b self, + pub(crate) fn obligations_for_self_ty( + &self, self_ty: ty::TyVid, - ) -> impl DoubleEndedIterator> + Captures<'tcx> + 'b - { - let ty_var_root = self.root_var(self_ty); - trace!("pending_obligations = {:#?}", self.fulfillment_cx.borrow().pending_obligations()); - - self.fulfillment_cx.borrow().pending_obligations().into_iter().filter_map( - move |obligation| match &obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) - if self.self_type_matches_expected_vid( - data.projection_ty.self_ty(), - ty_var_root, - ) => - { - Some(obligation) - } - ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) - if self.self_type_matches_expected_vid(data.self_ty(), ty_var_root) => - { - Some(obligation) - } - - ty::PredicateKind::Clause(ty::ClauseKind::Trait(..)) - | ty::PredicateKind::Clause(ty::ClauseKind::Projection(..)) - | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) - | ty::PredicateKind::Subtype(..) - | ty::PredicateKind::Coerce(..) - | ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..)) - | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..)) - | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..)) - | ty::PredicateKind::ObjectSafe(..) - | ty::PredicateKind::NormalizesTo(..) - | ty::PredicateKind::AliasRelate(..) - | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) - | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::Ambiguous => None, - }, - ) + ) -> Vec> { + if self.next_trait_solver() { + self.obligations_for_self_ty_next(self_ty) + } else { + let ty_var_root = self.root_var(self_ty); + let mut obligations = self.fulfillment_cx.borrow().pending_obligations(); + trace!("pending_obligations = {:#?}", obligations); + obligations + .retain(|obligation| self.predicate_has_self_ty(obligation.predicate, ty_var_root)); + obligations + } } #[instrument(level = "debug", skip(self), ret)] - fn self_type_matches_expected_vid(&self, self_ty: Ty<'tcx>, expected_vid: ty::TyVid) -> bool { - let self_ty = self.shallow_resolve(self_ty); - debug!(?self_ty); + fn predicate_has_self_ty( + &self, + predicate: ty::Predicate<'tcx>, + expected_vid: ty::TyVid, + ) -> bool { + match predicate.kind().skip_binder() { + ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => { + self.type_matches_expected_vid(expected_vid, data.self_ty()) + } + ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => { + self.type_matches_expected_vid(expected_vid, data.projection_ty.self_ty()) + } + ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) + | ty::PredicateKind::Subtype(..) + | ty::PredicateKind::Coerce(..) + | ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..)) + | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..)) + | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..)) + | ty::PredicateKind::ObjectSafe(..) + | ty::PredicateKind::NormalizesTo(..) + | ty::PredicateKind::AliasRelate(..) + | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) + | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous => false, + } + } - match *self_ty.kind() { + #[instrument(level = "debug", skip(self), ret)] + fn type_matches_expected_vid(&self, expected_vid: ty::TyVid, ty: Ty<'tcx>) -> bool { + let ty = self.shallow_resolve(ty); + debug!(?ty); + + match *ty.kind() { ty::Infer(ty::TyVar(found_vid)) => { - let found_vid = self.root_var(found_vid); - debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid); - expected_vid == found_vid + self.root_var(expected_vid) == self.root_var(found_vid) } _ => false, } } -} \ No newline at end of file + + pub(crate) fn obligations_for_self_ty_next( + &self, + self_ty: ty::TyVid, + ) -> Vec> { + let obligations = self.fulfillment_cx.borrow().pending_obligations(); + debug!(?obligations); + let mut obligations_for_self_ty = vec![]; + for obligation in obligations { + let mut visitor = NestedObligationsForSelfTy { + fcx: self, + self_ty, + obligations_for_self_ty: &mut obligations_for_self_ty, + root_cause: &obligation.cause, + }; + + let goal = Goal::new(self.tcx, obligation.param_env, obligation.predicate); + self.visit_proof_tree(goal, &mut visitor); + } + + obligations_for_self_ty.retain_mut(|obligation| { + obligation.predicate = self.resolve_vars_if_possible(obligation.predicate); + !obligation.predicate.has_placeholders() + }); + obligations_for_self_ty + } +} + +struct NestedObligationsForSelfTy<'a, 'tcx> { + fcx: &'a FnCtxt<'a, 'tcx>, + self_ty: ty::TyVid, + root_cause: &'a ObligationCause<'tcx>, + obligations_for_self_ty: &'a mut Vec>, +} + +impl<'a, 'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'a, 'tcx> { + type Result = (); + + fn span(&self) -> Span { + self.root_cause.span + } + + fn config(&self) -> InspectConfig { + // Using an intentionally low depth to minimize the chance of future + // breaking changes in case we adapt the approach later on. This also + // avoids any hangs for exponentially growing proof trees. + InspectConfig { max_depth: 5 } + } + + fn visit_goal(&mut self, inspect_goal: &InspectGoal<'_, 'tcx>) { + let tcx = self.fcx.tcx; + let goal = inspect_goal.goal(); + if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty) { + self.obligations_for_self_ty.push(traits::Obligation::new( + tcx, + self.root_cause.clone(), + goal.param_env, + goal.predicate, + )); + } + + // If there's a unique way to prove a given goal, recurse into + // that candidate. This means that for `impl Trait for () {}` + // and a `(): Trait` goal we recurse into the impl and look at + // the nested `?0: FnOnce(u32)` goal. + if let Some(candidate) = inspect_goal.unique_applicable_candidate() { + candidate.visit_nested_no_probe(self) + } + } +} diff --git a/compiler/rustc_middle/src/traits/solve/inspect.rs b/compiler/rustc_middle/src/traits/solve/inspect.rs index 52cdbae1e564..f2283e71dc87 100644 --- a/compiler/rustc_middle/src/traits/solve/inspect.rs +++ b/compiler/rustc_middle/src/traits/solve/inspect.rs @@ -102,6 +102,7 @@ pub struct Probe<'tcx> { /// What happened inside of this probe in chronological order. pub steps: Vec>, pub kind: ProbeKind<'tcx>, + pub final_state: CanonicalState<'tcx, ()>, } impl Debug for Probe<'_> { diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index 68b0db211413..952215290932 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -1,7 +1,7 @@ //! Code shared by trait and projection goals for candidate assembly. -use super::{EvalCtxt, SolverMode}; use crate::solve::GoalSource; +use crate::solve::{inspect, EvalCtxt, SolverMode}; use crate::traits::coherence; use rustc_hir::def_id::DefId; use rustc_infer::traits::query::NoSolution; @@ -16,6 +16,7 @@ use rustc_middle::ty::{fast_reject, TypeFoldable}; use rustc_middle::ty::{ToPredicate, TypeVisitableExt}; use rustc_span::{ErrorGuaranteed, DUMMY_SP}; use std::fmt::Debug; +use std::mem; pub(super) mod structural_traits; @@ -315,20 +316,17 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } fn forced_ambiguity(&mut self, cause: MaybeCause) -> Vec> { - let source = CandidateSource::BuiltinImpl(BuiltinImplSource::Misc); - let certainty = Certainty::Maybe(cause); // This may fail if `try_evaluate_added_goals` overflows because it // fails to reach a fixpoint but ends up getting an error after // running for some additional step. // - // FIXME: Add a test for this. It seems to be necessary for typenum but - // is incredibly hard to minimize as it may rely on being inside of a - // trait solver cycle. - let result = self.evaluate_added_goals_and_make_canonical_response(certainty); - let mut dummy_probe = self.inspect.new_probe(); - dummy_probe.probe_kind(ProbeKind::TraitCandidate { source, result }); - self.inspect.finish_probe(dummy_probe); - if let Ok(result) = result { vec![Candidate { source, result }] } else { vec![] } + // cc trait-system-refactor-initiative#105 + let source = CandidateSource::BuiltinImpl(BuiltinImplSource::Misc); + let certainty = Certainty::Maybe(cause); + let result = self + .probe_trait_candidate(source) + .enter(|this| this.evaluate_added_goals_and_make_canonical_response(certainty)); + if let Ok(cand) = result { vec![cand] } else { vec![] } } #[instrument(level = "debug", skip_all)] @@ -813,6 +811,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { goal: Goal<'tcx, G>, candidates: &mut Vec>, ) { + // HACK: We temporarily remove the `ProofTreeBuilder` to + // avoid adding `Trait` candidates to the candidates used + // to prove the current goal. + let inspect = mem::replace(&mut self.inspect, inspect::ProofTreeBuilder::new_noop()); + let tcx = self.tcx(); let trait_goal: Goal<'tcx, ty::TraitPredicate<'tcx>> = goal.with(tcx, goal.predicate.trait_ref(tcx)); @@ -846,6 +849,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } } + self.inspect = inspect; } /// If there are multiple ways to prove a trait or projection goal, we have diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index 0b37163d5970..9edeb0fa71b9 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -19,9 +19,12 @@ use rustc_infer::infer::canonical::query_response::make_query_region_constraints use rustc_infer::infer::canonical::CanonicalVarValues; use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints}; use rustc_infer::infer::resolve::EagerResolver; +use rustc_infer::infer::type_variable::TypeVariableOrigin; +use rustc_infer::infer::RegionVariableOrigin; use rustc_infer::infer::{InferCtxt, InferOk}; use rustc_infer::traits::solve::NestedNormalizationGoals; use rustc_middle::infer::canonical::Canonical; +use rustc_middle::infer::unify_key::ConstVariableOrigin; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{ ExternalConstraintsData, MaybeCause, PredefinedOpaquesData, QueryInput, @@ -29,7 +32,7 @@ use rustc_middle::traits::solve::{ use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{self, BoundVar, GenericArgKind, Ty, TyCtxt, TypeFoldable}; use rustc_next_trait_solver::canonicalizer::{CanonicalizeMode, Canonicalizer}; -use rustc_span::DUMMY_SP; +use rustc_span::{Span, DUMMY_SP}; use std::assert_matches::assert_matches; use std::iter; use std::ops::Deref; @@ -374,36 +377,70 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } -impl<'tcx> inspect::ProofTreeBuilder<'tcx> { - pub fn make_canonical_state>>( - ecx: &EvalCtxt<'_, 'tcx>, - data: T, - ) -> inspect::CanonicalState<'tcx, T> { - let state = inspect::State { var_values: ecx.var_values, data }; - let state = state.fold_with(&mut EagerResolver::new(ecx.infcx)); - Canonicalizer::canonicalize( - ecx.infcx, - CanonicalizeMode::Response { max_input_universe: ecx.max_input_universe }, - &mut vec![], - state, - ) - } - - /// Instantiate a `CanonicalState`. This assumes that unifying the var values - /// trivially succeeds. Adding any inference constraints which weren't present when - /// originally computing the canonical query can result in bugs. - pub fn instantiate_canonical_state>>( - infcx: &InferCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - original_values: &[ty::GenericArg<'tcx>], - state: inspect::CanonicalState<'tcx, T>, - ) -> T { - let instantiation = - EvalCtxt::compute_query_response_instantiation_values(infcx, original_values, &state); - - let inspect::State { var_values, data } = state.instantiate(infcx.tcx, &instantiation); - - EvalCtxt::unify_query_var_values(infcx, param_env, original_values, var_values); - data - } +/// Used by proof trees to be able to recompute intermediate actions while +/// evaluating a goal. The `var_values` not only include the bound variables +/// of the query input, but also contain all unconstrained inference vars +/// created while evaluating this goal. +pub(in crate::solve) fn make_canonical_state<'tcx, T: TypeFoldable>>( + infcx: &InferCtxt<'tcx>, + var_values: &[ty::GenericArg<'tcx>], + max_input_universe: ty::UniverseIndex, + data: T, +) -> inspect::CanonicalState<'tcx, T> { + let var_values = CanonicalVarValues { var_values: infcx.tcx.mk_args(var_values) }; + let state = inspect::State { var_values, data }; + let state = state.fold_with(&mut EagerResolver::new(infcx)); + Canonicalizer::canonicalize( + infcx, + CanonicalizeMode::Response { max_input_universe }, + &mut vec![], + state, + ) +} + +/// Instantiate a `CanonicalState`. +/// +/// Unlike for query responses, `CanonicalState` also track fresh inference +/// variables created while evaluating a goal. When creating two separate +/// `CanonicalState` during a single evaluation both may reference this +/// fresh inference variable. When instantiating them we now create separate +/// inference variables for it and have to unify them somehow. We do this +/// by extending the `var_values` while building the proof tree. +/// +/// This currently assumes that unifying the var values trivially succeeds. +/// Adding any inference constraints which weren't present when originally +/// computing the canonical query can result in bugs. +pub(in crate::solve) fn instantiate_canonical_state<'tcx, T: TypeFoldable>>( + infcx: &InferCtxt<'tcx>, + span: Span, + param_env: ty::ParamEnv<'tcx>, + orig_values: &mut Vec>, + state: inspect::CanonicalState<'tcx, T>, +) -> T { + // In case any fresh inference variables have been created between `state` + // and the previous instantiation, extend `orig_values` for it. + assert!(orig_values.len() <= state.value.var_values.len()); + for i in orig_values.len()..state.value.var_values.len() { + let unconstrained = match state.value.var_values.var_values[i].unpack() { + ty::GenericArgKind::Lifetime(_) => { + infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)).into() + } + ty::GenericArgKind::Type(_) => { + infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span }).into() + } + ty::GenericArgKind::Const(ct) => infcx + .next_const_var(ct.ty(), ConstVariableOrigin { param_def_id: None, span }) + .into(), + }; + + orig_values.push(unconstrained); + } + + let instantiation = + EvalCtxt::compute_query_response_instantiation_values(infcx, orig_values, &state); + + let inspect::State { var_values, data } = state.instantiate(infcx.tcx, &instantiation); + + EvalCtxt::unify_query_var_values(infcx, param_env, orig_values, var_values); + data } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index f914e6b3f2e8..21efce748792 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -34,7 +34,7 @@ use super::{search_graph::SearchGraph, Goal}; use super::{GoalSource, SolverMode}; pub use select::InferCtxtSelectExt; -mod canonical; +pub(super) mod canonical; mod probe; mod select; @@ -84,7 +84,7 @@ pub struct EvalCtxt<'a, 'tcx> { pub(super) search_graph: &'a mut SearchGraph<'tcx>, - pub(super) nested_goals: NestedGoals<'tcx>, + nested_goals: NestedGoals<'tcx>, // Has this `EvalCtxt` errored out with `NoSolution` in `try_evaluate_added_goals`? // @@ -161,7 +161,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { /// Creates a root evaluation context and search graph. This should only be /// used from outside of any evaluation, and other methods should be preferred /// over using this manually (such as [`InferCtxtEvalExt::evaluate_root_goal`]). - fn enter_root( + pub(super) fn enter_root( infcx: &InferCtxt<'tcx>, generate_proof_tree: GenerateProofTree, f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> R, @@ -242,7 +242,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { search_graph, nested_goals: NestedGoals::new(), tainted: Ok(()), - inspect: canonical_goal_evaluation.new_goal_evaluation_step(input), + inspect: canonical_goal_evaluation.new_goal_evaluation_step(var_values, input), }; for &(key, ty) in &input.predefined_opaques_in_body.opaque_types { @@ -255,7 +255,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } let result = f(&mut ecx, input.goal); - + ecx.inspect.probe_final_state(ecx.infcx, ecx.max_input_universe); canonical_goal_evaluation.goal_evaluation_step(ecx.inspect); // When creating a query response we clone the opaque type constraints @@ -338,7 +338,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { /// storage. // FIXME(-Znext-solver=coinduction): `_source` is currently unused but will // be necessary once we implement the new coinduction approach. - fn evaluate_goal_raw( + pub(super) fn evaluate_goal_raw( &mut self, goal_evaluation_kind: GoalEvaluationKind, _source: GoalSource, @@ -458,13 +458,23 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } } + #[instrument(level = "debug", skip(self))] + pub(super) fn add_normalizes_to_goal(&mut self, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>) { + self.inspect.add_normalizes_to_goal(self.infcx, self.max_input_universe, goal); + self.nested_goals.normalizes_to_goals.push(goal); + } + + #[instrument(level = "debug", skip(self))] + pub(super) fn add_goal(&mut self, source: GoalSource, goal: Goal<'tcx, ty::Predicate<'tcx>>) { + self.inspect.add_goal(self.infcx, self.max_input_universe, source, goal); + self.nested_goals.goals.push((source, goal)); + } + // Recursively evaluates all the goals added to this `EvalCtxt` to completion, returning // the certainty of all the goals. #[instrument(level = "debug", skip(self))] pub(super) fn try_evaluate_added_goals(&mut self) -> Result { - let inspect = self.inspect.new_evaluate_added_goals(); - let inspect = core::mem::replace(&mut self.inspect, inspect); - + self.inspect.start_evaluate_added_goals(); let mut response = Ok(Certainty::overflow(false)); for _ in 0..FIXPOINT_STEP_LIMIT { // FIXME: This match is a bit ugly, it might be nice to change the inspect @@ -482,15 +492,12 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } } - self.inspect.eval_added_goals_result(response); + self.inspect.evaluate_added_goals_result(response); if response.is_err() { self.tainted = Err(NoSolution); } - let goal_evaluations = std::mem::replace(&mut self.inspect, inspect); - self.inspect.added_goals_evaluation(goal_evaluations); - response } @@ -499,10 +506,9 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { /// Goals for the next step get directly added to the nested goals of the `EvalCtxt`. fn evaluate_added_goals_step(&mut self) -> Result, NoSolution> { let tcx = self.tcx(); + self.inspect.start_evaluate_added_goals_step(); let mut goals = core::mem::take(&mut self.nested_goals); - self.inspect.evaluate_added_goals_loop_start(); - // If this loop did not result in any progress, what's our final certainty. let mut unchanged_certainty = Some(Certainty::Yes); for goal in goals.normalizes_to_goals { @@ -586,17 +592,23 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.infcx.tcx } - pub(super) fn next_ty_infer(&self) -> Ty<'tcx> { - self.infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span: DUMMY_SP }) + pub(super) fn next_ty_infer(&mut self) -> Ty<'tcx> { + let ty = self.infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span: DUMMY_SP }); + self.inspect.add_var_value(ty); + ty } - pub(super) fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> { - self.infcx.next_const_var(ty, ConstVariableOrigin { param_def_id: None, span: DUMMY_SP }) + pub(super) fn next_const_infer(&mut self, ty: Ty<'tcx>) -> ty::Const<'tcx> { + let ct = self + .infcx + .next_const_var(ty, ConstVariableOrigin { param_def_id: None, span: DUMMY_SP }); + self.inspect.add_var_value(ct); + ct } /// Returns a ty infer or a const infer depending on whether `kind` is a `Ty` or `Const`. /// If `kind` is an integer inference variable this will still return a ty infer var. - pub(super) fn next_term_infer_of_kind(&self, kind: ty::Term<'tcx>) -> ty::Term<'tcx> { + pub(super) fn next_term_infer_of_kind(&mut self, kind: ty::Term<'tcx>) -> ty::Term<'tcx> { match kind.unpack() { ty::TermKind::Ty(_) => self.next_ty_infer().into(), ty::TermKind::Const(ct) => self.next_const_infer(ct.ty()).into(), diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs index 5b1124e8b9fc..9d59723e4415 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs @@ -20,23 +20,29 @@ where pub(in crate::solve) fn enter(self, f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> T) -> T { let ProbeCtxt { ecx: outer_ecx, probe_kind, _result } = self; + let infcx = outer_ecx.infcx; + let max_input_universe = outer_ecx.max_input_universe; let mut nested_ecx = EvalCtxt { - infcx: outer_ecx.infcx, + infcx, variables: outer_ecx.variables, var_values: outer_ecx.var_values, is_normalizes_to_goal: outer_ecx.is_normalizes_to_goal, predefined_opaques_in_body: outer_ecx.predefined_opaques_in_body, - max_input_universe: outer_ecx.max_input_universe, + max_input_universe, search_graph: outer_ecx.search_graph, nested_goals: outer_ecx.nested_goals.clone(), tainted: outer_ecx.tainted, - inspect: outer_ecx.inspect.new_probe(), + inspect: outer_ecx.inspect.take_and_enter_probe(), }; - let r = nested_ecx.infcx.probe(|_| f(&mut nested_ecx)); - if !outer_ecx.inspect.is_noop() { + let r = nested_ecx.infcx.probe(|_| { + let r = f(&mut nested_ecx); + nested_ecx.inspect.probe_final_state(infcx, max_input_universe); + r + }); + if !nested_ecx.inspect.is_noop() { let probe_kind = probe_kind(&r); nested_ecx.inspect.probe_kind(probe_kind); - outer_ecx.inspect.finish_probe(nested_ecx.inspect); + outer_ecx.inspect = nested_ecx.inspect.finish_probe(); } r } diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 56c32d3d5391..dbded4cbd37b 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -11,15 +11,24 @@ use rustc_ast_ir::try_visit; use rustc_ast_ir::visit::VisitorResult; -use rustc_infer::infer::InferCtxt; +use rustc_infer::infer::type_variable::TypeVariableOrigin; +use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; +use rustc_middle::infer::unify_key::ConstVariableOrigin; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{inspect, QueryResult}; use rustc_middle::traits::solve::{Certainty, Goal}; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty; +use rustc_span::Span; -use crate::solve::inspect::ProofTreeBuilder; +use crate::solve::eval_ctxt::canonical; +use crate::solve::{EvalCtxt, GoalEvaluationKind, GoalSource}; use crate::solve::{GenerateProofTree, InferCtxtEvalExt}; +pub struct InspectConfig { + pub max_depth: usize, +} + pub struct InspectGoal<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, depth: usize, @@ -32,14 +41,11 @@ pub struct InspectCandidate<'a, 'tcx> { goal: &'a InspectGoal<'a, 'tcx>, kind: inspect::ProbeKind<'tcx>, nested_goals: Vec>>>, + final_state: inspect::CanonicalState<'tcx, ()>, result: QueryResult<'tcx>, } impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { - pub fn infcx(&self) -> &'a InferCtxt<'tcx> { - self.goal.infcx - } - pub fn kind(&self) -> inspect::ProbeKind<'tcx> { self.kind } @@ -48,55 +54,88 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { self.result.map(|c| c.value.certainty) } - /// Visit the nested goals of this candidate. - /// - /// FIXME(@lcnr): we have to slightly adapt this API - /// to also use it to compute the most relevant goal - /// for fulfillment errors. Will do that once we actually - /// need it. - pub fn visit_nested>(&self, visitor: &mut V) -> V::Result { - // HACK: An arbitrary cutoff to avoid dealing with overflow and cycles. - if self.goal.depth <= 10 { + /// Visit all nested goals of this candidate without rolling + /// back their inference constraints. This function modifies + /// the state of the `infcx`. + pub fn visit_nested_no_probe>(&self, visitor: &mut V) -> V::Result { + if self.goal.depth < visitor.config().max_depth { let infcx = self.goal.infcx; - infcx.probe(|_| { - let mut instantiated_goals = vec![]; - for goal in &self.nested_goals { - let goal = ProofTreeBuilder::instantiate_canonical_state( - infcx, - self.goal.goal.param_env, - self.goal.orig_values, - *goal, - ); - instantiated_goals.push(goal); - } + let param_env = self.goal.goal.param_env; + let mut orig_values = self.goal.orig_values.to_vec(); + let mut instantiated_goals = vec![]; + for goal in &self.nested_goals { + let goal = canonical::instantiate_canonical_state( + infcx, + visitor.span(), + param_env, + &mut orig_values, + *goal, + ); + instantiated_goals.push(goal); + } - for goal in instantiated_goals.iter().copied() { - // We need to be careful with `NormalizesTo` goals as the - // expected term has to be replaced with an unconstrained - // inference variable. - if let Some(kind) = goal.predicate.kind().no_bound_vars() - && let ty::PredicateKind::NormalizesTo(predicate) = kind - && !predicate.alias.is_opaque(infcx.tcx) - { - // FIXME: We currently skip these goals as - // `fn evaluate_root_goal` ICEs if there are any - // `NestedNormalizationGoals`. - continue; - }; - let (_, proof_tree) = infcx.evaluate_root_goal(goal, GenerateProofTree::Yes); - let proof_tree = proof_tree.unwrap(); - try_visit!(visitor.visit_goal(&InspectGoal::new( - infcx, - self.goal.depth + 1, - &proof_tree, - ))); - } + let () = canonical::instantiate_canonical_state( + infcx, + visitor.span(), + param_env, + &mut orig_values, + self.final_state, + ); - V::Result::output() - }) - } else { - V::Result::output() + for &goal in &instantiated_goals { + let proof_tree = match goal.predicate.kind().no_bound_vars() { + Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => { + let unconstrained_term = match term.unpack() { + ty::TermKind::Ty(_) => infcx + .next_ty_var(TypeVariableOrigin { + param_def_id: None, + span: visitor.span(), + }) + .into(), + ty::TermKind::Const(ct) => infcx + .next_const_var( + ct.ty(), + ConstVariableOrigin { + param_def_id: None, + span: visitor.span(), + }, + ) + .into(), + }; + let goal = goal + .with(infcx.tcx, ty::NormalizesTo { alias, term: unconstrained_term }); + let proof_tree = + EvalCtxt::enter_root(infcx, GenerateProofTree::Yes, |ecx| { + ecx.evaluate_goal_raw( + GoalEvaluationKind::Root, + GoalSource::Misc, + goal, + ) + }) + .1; + let InferOk { value: (), obligations: _ } = infcx + .at(&ObligationCause::dummy(), param_env) + .eq(DefineOpaqueTypes::Yes, term, unconstrained_term) + .unwrap(); + proof_tree + } + _ => infcx.evaluate_root_goal(goal, GenerateProofTree::Yes).1, + }; + try_visit!(visitor.visit_goal(&InspectGoal::new( + infcx, + self.goal.depth + 1, + &proof_tree.unwrap(), + ))); + } } + + V::Result::output() + } + + /// Visit all nested goals of this candidate, rolling back + /// all inference constraints. + pub fn visit_nested_in_probe>(&self, visitor: &mut V) -> V::Result { + self.goal.infcx.probe(|_| self.visit_nested_no_probe(visitor)) } } @@ -119,6 +158,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { nested_goals: &mut Vec>>>, probe: &inspect::Probe<'tcx>, ) { + let num_candidates = candidates.len(); for step in &probe.steps { match step { &inspect::ProbeStep::AddGoal(_source, goal) => nested_goals.push(goal), @@ -144,23 +184,25 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { // FIXME: This is currently wrong if we don't even try any // candidates, e.g. for a trait goal, as in this case `candidates` is // actually supposed to be empty. - inspect::ProbeKind::Root { result } => { - if candidates.is_empty() { + inspect::ProbeKind::Root { result } + | inspect::ProbeKind::TryNormalizeNonRigid { result } => { + if candidates.len() == num_candidates { candidates.push(InspectCandidate { goal: self, kind: probe.kind, nested_goals: nested_goals.clone(), + final_state: probe.final_state, result, - }); + }) } } - inspect::ProbeKind::TryNormalizeNonRigid { result } - | inspect::ProbeKind::MiscCandidate { name: _, result } + inspect::ProbeKind::MiscCandidate { name: _, result } | inspect::ProbeKind::TraitCandidate { source: _, result } => { candidates.push(InspectCandidate { goal: self, kind: probe.kind, nested_goals: nested_goals.clone(), + final_state: probe.final_state, result, }); } @@ -191,6 +233,17 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { candidates } + /// Returns the single candidate applicable for the current goal, if it exists. + /// + /// Returns `None` if there are either no or multiple applicable candidates. + pub fn unique_applicable_candidate(&'a self) -> Option> { + // FIXME(-Znext-solver): This does not handle impl candidates + // hidden by env candidates. + let mut candidates = self.candidates(); + candidates.retain(|c| c.result().is_ok()); + candidates.pop().filter(|_| candidates.is_empty()) + } + fn new( infcx: &'a InferCtxt<'tcx>, depth: usize, @@ -213,6 +266,12 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { pub trait ProofTreeVisitor<'tcx> { type Result: VisitorResult = (); + fn span(&self) -> Span; + + fn config(&self) -> InspectConfig { + InspectConfig { max_depth: 10 } + } + fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) -> Self::Result; } @@ -223,10 +282,8 @@ impl<'tcx> InferCtxt<'tcx> { goal: Goal<'tcx, ty::Predicate<'tcx>>, visitor: &mut V, ) -> V::Result { - self.probe(|_| { - let (_, proof_tree) = self.evaluate_root_goal(goal, GenerateProofTree::Yes); - let proof_tree = proof_tree.unwrap(); - visitor.visit_goal(&InspectGoal::new(self, 0, &proof_tree)) - }) + let (_, proof_tree) = self.evaluate_root_goal(goal, GenerateProofTree::Yes); + let proof_tree = proof_tree.unwrap(); + visitor.visit_goal(&InspectGoal::new(self, 0, &proof_tree)) } } diff --git a/compiler/rustc_trait_selection/src/solve/inspect/build.rs b/compiler/rustc_trait_selection/src/solve/inspect/build.rs index 43c76cc5f4a0..c3651517d490 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/build.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/build.rs @@ -5,6 +5,8 @@ //! see the comment on [ProofTreeBuilder]. use std::mem; +use rustc_infer::infer::InferCtxt; +use rustc_middle::infer::canonical::CanonicalVarValues; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{ CanonicalInput, Certainty, Goal, GoalSource, QueryInput, QueryResult, @@ -12,7 +14,8 @@ use rustc_middle::traits::solve::{ use rustc_middle::ty::{self, TyCtxt}; use rustc_session::config::DumpSolverProofTree; -use crate::solve::{self, inspect, EvalCtxt, GenerateProofTree}; +use crate::solve::eval_ctxt::canonical; +use crate::solve::{self, inspect, GenerateProofTree}; /// The core data structure when building proof trees. /// @@ -47,9 +50,7 @@ enum DebugSolver<'tcx> { Root, GoalEvaluation(WipGoalEvaluation<'tcx>), CanonicalGoalEvaluation(WipCanonicalGoalEvaluation<'tcx>), - AddedGoalsEvaluation(WipAddedGoalsEvaluation<'tcx>), GoalEvaluationStep(WipGoalEvaluationStep<'tcx>), - Probe(WipProbe<'tcx>), } impl<'tcx> From> for DebugSolver<'tcx> { @@ -64,24 +65,12 @@ impl<'tcx> From> for DebugSolver<'tcx> { } } -impl<'tcx> From> for DebugSolver<'tcx> { - fn from(g: WipAddedGoalsEvaluation<'tcx>) -> DebugSolver<'tcx> { - DebugSolver::AddedGoalsEvaluation(g) - } -} - impl<'tcx> From> for DebugSolver<'tcx> { fn from(g: WipGoalEvaluationStep<'tcx>) -> DebugSolver<'tcx> { DebugSolver::GoalEvaluationStep(g) } } -impl<'tcx> From> for DebugSolver<'tcx> { - fn from(p: WipProbe<'tcx>) -> DebugSolver<'tcx> { - DebugSolver::Probe(p) - } -} - #[derive(Eq, PartialEq, Debug)] struct WipGoalEvaluation<'tcx> { pub uncanonicalized_goal: Goal<'tcx, ty::Predicate<'tcx>>, @@ -184,12 +173,41 @@ impl<'tcx> WipAddedGoalsEvaluation<'tcx> { #[derive(Eq, PartialEq, Debug)] struct WipGoalEvaluationStep<'tcx> { + /// Unlike `EvalCtxt::var_values`, we append a new + /// generic arg here whenever we create a new inference + /// variable. + /// + /// This is necessary as we otherwise don't unify these + /// vars when instantiating multiple `CanonicalState`. + var_values: Vec>, instantiated_goal: QueryInput<'tcx, ty::Predicate<'tcx>>, - + probe_depth: usize, evaluation: WipProbe<'tcx>, } impl<'tcx> WipGoalEvaluationStep<'tcx> { + fn current_evaluation_scope(&mut self) -> &mut WipProbe<'tcx> { + let mut current = &mut self.evaluation; + for _ in 0..self.probe_depth { + match current.steps.last_mut() { + Some(WipProbeStep::NestedProbe(p)) => current = p, + _ => bug!(), + } + } + current + } + + fn added_goals_evaluation(&mut self) -> &mut WipAddedGoalsEvaluation<'tcx> { + let mut current = &mut self.evaluation; + loop { + match current.steps.last_mut() { + Some(WipProbeStep::NestedProbe(p)) => current = p, + Some(WipProbeStep::EvaluateGoals(evaluation)) => return evaluation, + _ => bug!(), + } + } + } + fn finalize(self) -> inspect::GoalEvaluationStep<'tcx> { let evaluation = self.evaluation.finalize(); match evaluation.kind { @@ -202,8 +220,10 @@ impl<'tcx> WipGoalEvaluationStep<'tcx> { #[derive(Eq, PartialEq, Debug)] struct WipProbe<'tcx> { - pub steps: Vec>, - pub kind: Option>, + initial_num_var_values: usize, + steps: Vec>, + kind: Option>, + final_state: Option>, } impl<'tcx> WipProbe<'tcx> { @@ -211,6 +231,7 @@ impl<'tcx> WipProbe<'tcx> { inspect::Probe { steps: self.steps.into_iter().map(WipProbeStep::finalize).collect(), kind: self.kind.unwrap(), + final_state: self.final_state.unwrap(), } } } @@ -245,6 +266,12 @@ impl<'tcx> ProofTreeBuilder<'tcx> { self.state.as_deref_mut() } + pub fn take_and_enter_probe(&mut self) -> ProofTreeBuilder<'tcx> { + let mut nested = ProofTreeBuilder { state: self.state.take() }; + nested.enter_probe(); + nested + } + pub fn finalize(self) -> Option> { match *self.state? { DebugSolver::GoalEvaluation(wip_goal_evaluation) => { @@ -362,11 +389,14 @@ impl<'tcx> ProofTreeBuilder<'tcx> { if let Some(this) = self.as_mut() { match (this, *goal_evaluation.state.unwrap()) { ( - DebugSolver::AddedGoalsEvaluation(WipAddedGoalsEvaluation { - evaluations, .. - }), + DebugSolver::GoalEvaluationStep(state), DebugSolver::GoalEvaluation(goal_evaluation), - ) => evaluations.last_mut().unwrap().push(goal_evaluation), + ) => state + .added_goals_evaluation() + .evaluations + .last_mut() + .unwrap() + .push(goal_evaluation), (this @ DebugSolver::Root, goal_evaluation) => *this = goal_evaluation, _ => unreachable!(), } @@ -375,13 +405,22 @@ impl<'tcx> ProofTreeBuilder<'tcx> { pub fn new_goal_evaluation_step( &mut self, + var_values: CanonicalVarValues<'tcx>, instantiated_goal: QueryInput<'tcx, ty::Predicate<'tcx>>, ) -> ProofTreeBuilder<'tcx> { self.nested(|| WipGoalEvaluationStep { + var_values: var_values.var_values.to_vec(), instantiated_goal, - evaluation: WipProbe { steps: vec![], kind: None }, + evaluation: WipProbe { + initial_num_var_values: var_values.len(), + steps: vec![], + kind: None, + final_state: None, + }, + probe_depth: 0, }) } + pub fn goal_evaluation_step(&mut self, goal_evaluation_step: ProofTreeBuilder<'tcx>) { if let Some(this) = self.as_mut() { match (this, *goal_evaluation_step.state.unwrap()) { @@ -396,112 +435,146 @@ impl<'tcx> ProofTreeBuilder<'tcx> { } } - pub fn new_probe(&mut self) -> ProofTreeBuilder<'tcx> { - self.nested(|| WipProbe { steps: vec![], kind: None }) + pub fn add_var_value>>(&mut self, arg: T) { + match self.as_mut() { + None => {} + Some(DebugSolver::GoalEvaluationStep(state)) => { + state.var_values.push(arg.into()); + } + Some(s) => bug!("tried to add var values to {s:?}"), + } + } + + pub fn enter_probe(&mut self) { + match self.as_mut() { + None => {} + Some(DebugSolver::GoalEvaluationStep(state)) => { + let initial_num_var_values = state.var_values.len(); + state.current_evaluation_scope().steps.push(WipProbeStep::NestedProbe(WipProbe { + initial_num_var_values, + steps: vec![], + kind: None, + final_state: None, + })); + state.probe_depth += 1; + } + Some(s) => bug!("tried to start probe to {s:?}"), + } } pub fn probe_kind(&mut self, probe_kind: inspect::ProbeKind<'tcx>) { - if let Some(this) = self.as_mut() { - match this { - DebugSolver::Probe(this) => { - assert_eq!(this.kind.replace(probe_kind), None) - } - _ => unreachable!(), + match self.as_mut() { + None => {} + Some(DebugSolver::GoalEvaluationStep(state)) => { + let prev = state.current_evaluation_scope().kind.replace(probe_kind); + assert_eq!(prev, None); } + _ => bug!(), + } + } + + pub fn probe_final_state( + &mut self, + infcx: &InferCtxt<'tcx>, + max_input_universe: ty::UniverseIndex, + ) { + match self.as_mut() { + None => {} + Some(DebugSolver::GoalEvaluationStep(state)) => { + let final_state = canonical::make_canonical_state( + infcx, + &state.var_values, + max_input_universe, + (), + ); + let prev = state.current_evaluation_scope().final_state.replace(final_state); + assert_eq!(prev, None); + } + _ => bug!(), } } pub fn add_normalizes_to_goal( - ecx: &mut EvalCtxt<'_, 'tcx>, + &mut self, + infcx: &InferCtxt<'tcx>, + max_input_universe: ty::UniverseIndex, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>, ) { - if ecx.inspect.is_noop() { - return; - } - - Self::add_goal(ecx, GoalSource::Misc, goal.with(ecx.tcx(), goal.predicate)); + self.add_goal( + infcx, + max_input_universe, + GoalSource::Misc, + goal.with(infcx.tcx, goal.predicate), + ); } pub fn add_goal( - ecx: &mut EvalCtxt<'_, 'tcx>, + &mut self, + infcx: &InferCtxt<'tcx>, + max_input_universe: ty::UniverseIndex, source: GoalSource, goal: Goal<'tcx, ty::Predicate<'tcx>>, ) { - // Can't use `if let Some(this) = ecx.inspect.as_mut()` here because - // we have to immutably use the `EvalCtxt` for `make_canonical_state`. - if ecx.inspect.is_noop() { - return; - } - - let goal = Self::make_canonical_state(ecx, goal); - - match ecx.inspect.as_mut().unwrap() { - DebugSolver::GoalEvaluationStep(WipGoalEvaluationStep { - evaluation: WipProbe { steps, .. }, - .. - }) - | DebugSolver::Probe(WipProbe { steps, .. }) => { - steps.push(WipProbeStep::AddGoal(source, goal)) + match self.as_mut() { + None => {} + Some(DebugSolver::GoalEvaluationStep(state)) => { + let goal = canonical::make_canonical_state( + infcx, + &state.var_values, + max_input_universe, + goal, + ); + state.current_evaluation_scope().steps.push(WipProbeStep::AddGoal(source, goal)) } - s => unreachable!("tried to add {goal:?} to {s:?}"), + _ => bug!(), } } - pub fn finish_probe(&mut self, probe: ProofTreeBuilder<'tcx>) { - if let Some(this) = self.as_mut() { - match (this, *probe.state.unwrap()) { - ( - DebugSolver::Probe(WipProbe { steps, .. }) - | DebugSolver::GoalEvaluationStep(WipGoalEvaluationStep { - evaluation: WipProbe { steps, .. }, - .. - }), - DebugSolver::Probe(probe), - ) => steps.push(WipProbeStep::NestedProbe(probe)), - _ => unreachable!(), + pub fn finish_probe(mut self) -> ProofTreeBuilder<'tcx> { + match self.as_mut() { + None => {} + Some(DebugSolver::GoalEvaluationStep(state)) => { + assert_ne!(state.probe_depth, 0); + let num_var_values = state.current_evaluation_scope().initial_num_var_values; + state.var_values.truncate(num_var_values); + state.probe_depth -= 1; } + _ => bug!(), + } + + self + } + + pub fn start_evaluate_added_goals(&mut self) { + match self.as_mut() { + None => {} + Some(DebugSolver::GoalEvaluationStep(state)) => { + state.current_evaluation_scope().steps.push(WipProbeStep::EvaluateGoals( + WipAddedGoalsEvaluation { evaluations: vec![], result: None }, + )); + } + _ => bug!(), } } - pub fn new_evaluate_added_goals(&mut self) -> ProofTreeBuilder<'tcx> { - self.nested(|| WipAddedGoalsEvaluation { evaluations: vec![], result: None }) - } - - pub fn evaluate_added_goals_loop_start(&mut self) { - if let Some(this) = self.as_mut() { - match this { - DebugSolver::AddedGoalsEvaluation(this) => { - this.evaluations.push(vec![]); - } - _ => unreachable!(), + pub fn start_evaluate_added_goals_step(&mut self) { + match self.as_mut() { + None => {} + Some(DebugSolver::GoalEvaluationStep(state)) => { + state.added_goals_evaluation().evaluations.push(vec![]); } + _ => bug!(), } } - pub fn eval_added_goals_result(&mut self, result: Result) { - if let Some(this) = self.as_mut() { - match this { - DebugSolver::AddedGoalsEvaluation(this) => { - assert_eq!(this.result.replace(result), None); - } - _ => unreachable!(), - } - } - } - - pub fn added_goals_evaluation(&mut self, added_goals_evaluation: ProofTreeBuilder<'tcx>) { - if let Some(this) = self.as_mut() { - match (this, *added_goals_evaluation.state.unwrap()) { - ( - DebugSolver::GoalEvaluationStep(WipGoalEvaluationStep { - evaluation: WipProbe { steps, .. }, - .. - }) - | DebugSolver::Probe(WipProbe { steps, .. }), - DebugSolver::AddedGoalsEvaluation(added_goals_evaluation), - ) => steps.push(WipProbeStep::EvaluateGoals(added_goals_evaluation)), - _ => unreachable!(), + pub fn evaluate_added_goals_result(&mut self, result: Result) { + match self.as_mut() { + None => {} + Some(DebugSolver::GoalEvaluationStep(state)) => { + let prev = state.added_goals_evaluation().result.replace(result); + assert_eq!(prev, None); } + _ => bug!(), } } diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index da5cd15a10d7..e58babe32089 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -200,18 +200,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } impl<'tcx> EvalCtxt<'_, 'tcx> { - #[instrument(level = "debug", skip(self))] - fn add_normalizes_to_goal(&mut self, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>) { - inspect::ProofTreeBuilder::add_normalizes_to_goal(self, goal); - self.nested_goals.normalizes_to_goals.push(goal); - } - - #[instrument(level = "debug", skip(self))] - fn add_goal(&mut self, source: GoalSource, goal: Goal<'tcx, ty::Predicate<'tcx>>) { - inspect::ProofTreeBuilder::add_goal(self, source, goal); - self.nested_goals.goals.push((source, goal)); - } - #[instrument(level = "debug", skip(self, goals))] fn add_goals( &mut self, diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 36028b516591..a4208cdc3c62 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -30,7 +30,7 @@ use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor}; use rustc_span::symbol::sym; -use rustc_span::DUMMY_SP; +use rustc_span::{Span, DUMMY_SP}; use std::fmt::Debug; use std::ops::ControlFlow; @@ -1022,10 +1022,14 @@ struct AmbiguityCausesVisitor<'a, 'tcx> { } impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> { + fn span(&self) -> Span { + DUMMY_SP + } + fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) { let infcx = goal.infcx(); for cand in goal.candidates() { - cand.visit_nested(self); + cand.visit_nested_in_probe(self); } // When searching for intercrate ambiguity causes, we only need to look // at ambiguous goals, as for others the coherence unknowable candidate @@ -1157,5 +1161,5 @@ fn search_ambiguity_causes<'tcx>( goal: Goal<'tcx, ty::Predicate<'tcx>>, causes: &mut FxIndexSet>, ) { - infcx.visit_proof_tree(goal, &mut AmbiguityCausesVisitor { causes }); + infcx.probe(|_| infcx.visit_proof_tree(goal, &mut AmbiguityCausesVisitor { causes })); } diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index dff15265fae7..4f02a61f7bc7 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -439,7 +439,6 @@ ui/closures/issue-11873.rs ui/closures/issue-1460.rs ui/closures/issue-22864-1.rs ui/closures/issue-22864-2.rs -ui/closures/issue-23012-supertrait-signature-inference.rs ui/closures/issue-25439.rs ui/closures/issue-41366.rs ui/closures/issue-42463.rs diff --git a/tests/ui/closures/deduce-signature/deduce-from-opaque-type-after-norm.rs b/tests/ui/closures/deduce-signature/deduce-from-opaque-type-after-norm.rs new file mode 100644 index 000000000000..9885d381d244 --- /dev/null +++ b/tests/ui/closures/deduce-signature/deduce-from-opaque-type-after-norm.rs @@ -0,0 +1,11 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@ check-pass +trait Foo { + fn test() -> impl Fn(u32) -> u32 { + |x| x.count_ones() + } +} + +fn main() {} diff --git a/tests/ui/closures/deduce-signature/deduce-from-opaque-type.rs b/tests/ui/closures/deduce-signature/deduce-from-opaque-type.rs new file mode 100644 index 000000000000..3185a431f0ba --- /dev/null +++ b/tests/ui/closures/deduce-signature/deduce-from-opaque-type.rs @@ -0,0 +1,9 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@ check-pass +fn foo() -> impl FnOnce(u32) -> u32 { + |x| x.leading_zeros() +} + +fn main() {} diff --git a/tests/ui/closures/deduce-signature/infer-higher-ranked-signature.rs b/tests/ui/closures/deduce-signature/infer-higher-ranked-signature.rs new file mode 100644 index 000000000000..d9ab0149087e --- /dev/null +++ b/tests/ui/closures/deduce-signature/infer-higher-ranked-signature.rs @@ -0,0 +1,20 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@ check-pass + +trait Foo {} +fn needs_foo(_: T) +where + Wrap: Foo, +{ +} + +struct Wrap(T); +impl Foo for Wrap where T: for<'a> Fn(&'a i32) {} + +fn main() { + needs_foo(|x| { + x.to_string(); + }); +} diff --git a/tests/ui/closures/infer-signature-from-impl.rs b/tests/ui/closures/deduce-signature/infer-signature-from-impl.rs similarity index 79% rename from tests/ui/closures/infer-signature-from-impl.rs rename to tests/ui/closures/deduce-signature/infer-signature-from-impl.rs index fa455c15ec79..20802ce37ee6 100644 --- a/tests/ui/closures/infer-signature-from-impl.rs +++ b/tests/ui/closures/deduce-signature/infer-signature-from-impl.rs @@ -1,8 +1,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next] known-bug: trait-system-refactor-initiative#71 -//@[current] check-pass +//@ check-pass trait Foo {} fn needs_foo(_: T) diff --git a/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.current.stderr b/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.current.stderr new file mode 100644 index 000000000000..eaa0d32e75df --- /dev/null +++ b/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.current.stderr @@ -0,0 +1,15 @@ +error: implementation of `Foo` is not general enough + --> $DIR/obligation-with-leaking-placeholders.rs:18:5 + | +LL | / needs_foo(|x| { +LL | | +LL | | +LL | | x.to_string(); +LL | | }); + | |______^ implementation of `Foo` is not general enough + | + = note: `Wrap<{closure@$DIR/obligation-with-leaking-placeholders.rs:18:15: 18:18}>` must implement `Foo<'0>`, for any lifetime `'0`... + = note: ...but it actually implements `Foo<'1>`, for some specific lifetime `'1` + +error: aborting due to 1 previous error + diff --git a/tests/ui/closures/infer-signature-from-impl.next.stderr b/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.next.stderr similarity index 87% rename from tests/ui/closures/infer-signature-from-impl.next.stderr rename to tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.next.stderr index 332917eaaff0..3d667f12371a 100644 --- a/tests/ui/closures/infer-signature-from-impl.next.stderr +++ b/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.next.stderr @@ -1,8 +1,9 @@ error[E0282]: type annotations needed - --> $DIR/infer-signature-from-impl.rs:18:16 + --> $DIR/obligation-with-leaking-placeholders.rs:18:16 | LL | needs_foo(|x| { | ^ +... LL | x.to_string(); | - type must be known at this point | diff --git a/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.rs b/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.rs new file mode 100644 index 000000000000..deb888ec2867 --- /dev/null +++ b/tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.rs @@ -0,0 +1,23 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// See #124385 for more details. + +trait Foo<'a> {} +fn needs_foo(_: T) +where + for<'a> Wrap: Foo<'a>, +{ +} + +struct Wrap(T); +impl<'a, T> Foo<'a> for Wrap where T: Fn(&'a i32) {} + +fn main() { + needs_foo(|x| { + //[current]~^ implementation of `Foo` is not general enough + //[next]~^^ ERROR type annotations needed + x.to_string(); + }); +} diff --git a/tests/ui/closures/issue-23012-supertrait-signature-inference.rs b/tests/ui/closures/deduce-signature/supertrait-signature-inference-issue-23012.rs similarity index 84% rename from tests/ui/closures/issue-23012-supertrait-signature-inference.rs rename to tests/ui/closures/deduce-signature/supertrait-signature-inference-issue-23012.rs index 732f687309ce..16890b28acd8 100644 --- a/tests/ui/closures/issue-23012-supertrait-signature-inference.rs +++ b/tests/ui/closures/deduce-signature/supertrait-signature-inference-issue-23012.rs @@ -1,3 +1,6 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver //@ check-pass // Checks that we can infer a closure signature even if the `FnOnce` bound is // a supertrait of the obligations we have currently registered for the Ty var. diff --git a/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs b/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs deleted file mode 100644 index a0fe7f0d0a5b..000000000000 --- a/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ compile-flags: -Znext-solver -// FIXME(-Znext-solver): This test is currently broken because the `deduce_closure_signature` -// is unable to look at nested obligations. -trait Foo { - fn test() -> impl Fn(u32) -> u32 { - |x| x.count_ones() - //~^ ERROR type annotations needed - } -} - -fn main() {} diff --git a/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.stderr b/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.stderr deleted file mode 100644 index 3d7cd1af4677..000000000000 --- a/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/deduce-closure-signature-after-normalization.rs:6:10 - | -LL | |x| x.count_ones() - | ^ - type must be known at this point - | -help: consider giving this closure parameter an explicit type - | -LL | |x: /* Type */| x.count_ones() - | ++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0282`. From 43f21a6871542df7546d9858d258207d947d3d2c Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Thu, 25 Apr 2024 12:32:11 -0700 Subject: [PATCH 058/279] thread_local: split refs to fields of Key --- library/std/src/sys/thread_local/fast_local.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys/thread_local/fast_local.rs b/library/std/src/sys/thread_local/fast_local.rs index 69ee70de30c0..49b51a729e42 100644 --- a/library/std/src/sys/thread_local/fast_local.rs +++ b/library/std/src/sys/thread_local/fast_local.rs @@ -1,7 +1,7 @@ use super::lazy::LazyKeyInner; use crate::cell::Cell; use crate::sys::thread_local_dtor::register_dtor; -use crate::{fmt, mem, panic}; +use crate::{fmt, mem, panic, ptr}; #[doc(hidden)] #[allow_internal_unstable(thread_local_internals, cfg_target_thread_local, thread_local)] @@ -237,8 +237,9 @@ unsafe extern "C" fn destroy_value(ptr: *mut u8) { // Wrap the call in a catch to ensure unwinding is caught in the event // a panic takes place in a destructor. if let Err(_) = panic::catch_unwind(panic::AssertUnwindSafe(|| unsafe { - let value = (*ptr).inner.take(); - (*ptr).dtor_state.set(DtorState::RunningOrHasRun); + let Key { inner, dtor_state } = &*ptr; + let value = inner.take(); + dtor_state.set(DtorState::RunningOrHasRun); drop(value); })) { rtabort!("thread local panicked on drop"); From 5be9fdd636c0c13eb9b933227a401e5873e46f89 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 24 Apr 2024 20:31:51 +0300 Subject: [PATCH 059/279] ast: Generalize item kind visiting And avoid duplicating logic for visiting `Item`s with different kinds (regular, associated, foreign). --- compiler/rustc_ast/src/mut_visit.rs | 356 +++++++++--------- compiler/rustc_ast/src/visit.rs | 296 ++++++++------- compiler/rustc_ast_lowering/src/lib.rs | 2 +- .../rustc_ast_passes/src/ast_validation.rs | 2 +- compiler/rustc_ast_passes/src/feature_gate.rs | 2 +- compiler/rustc_ast_passes/src/node_count.rs | 2 +- compiler/rustc_builtin_macros/src/cfg_eval.rs | 6 +- compiler/rustc_expand/src/expand.rs | 6 +- compiler/rustc_expand/src/placeholders.rs | 6 +- compiler/rustc_lint/src/early.rs | 2 +- compiler/rustc_passes/src/hir_stats.rs | 2 +- .../rustc_resolve/src/build_reduced_graph.rs | 2 +- compiler/rustc_resolve/src/def_collector.rs | 2 +- compiler/rustc_resolve/src/late.rs | 8 +- .../tests/ui/tabs_in_doc_comments.stderr | 54 +-- .../feature-gate-optimize_attribute.stderr | 20 +- .../issue-43106-gating-of-stable.stderr | 12 +- .../issue-43106-gating-of-unstable.stderr | 12 +- 18 files changed, 410 insertions(+), 382 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 1cceca33c175..2ff8098035d7 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -34,6 +34,10 @@ impl ExpectOne for SmallVec { } } +pub trait NoopVisitItemKind { + fn noop_visit(&mut self, visitor: &mut impl MutVisitor); +} + pub trait MutVisitor: Sized { /// Mutable token visiting only exists for the `macro_rules` token marker and should not be /// used otherwise. Token visitor would be entirely separate from the regular visitor if @@ -90,7 +94,7 @@ pub trait MutVisitor: Sized { } fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { - noop_flat_map_foreign_item(ni, self) + noop_flat_map_item(ni, self) } fn flat_map_item(&mut self, i: P) -> SmallVec<[P; 1]> { @@ -105,16 +109,12 @@ pub trait MutVisitor: Sized { noop_flat_map_field_def(fd, self) } - fn visit_item_kind(&mut self, i: &mut ItemKind) { - noop_visit_item_kind(i, self); - } - fn flat_map_trait_item(&mut self, i: P) -> SmallVec<[P; 1]> { - noop_flat_map_assoc_item(i, self) + noop_flat_map_item(i, self) } fn flat_map_impl_item(&mut self, i: P) -> SmallVec<[P; 1]> { - noop_flat_map_assoc_item(i, self) + noop_flat_map_item(i, self) } fn visit_fn_decl(&mut self, d: &mut P) { @@ -1068,149 +1068,151 @@ pub fn noop_visit_block(block: &mut P, vis: &mut T) { visit_lazy_tts(tokens, vis); } -pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) { - match kind { - ItemKind::ExternCrate(_orig_name) => {} - ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree), - ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => { - vis.visit_ty(ty); - visit_opt(expr, |expr| vis.visit_expr(expr)); - } - ItemKind::Const(item) => { - visit_const_item(item, vis); - } - ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visit_defaultness(defaultness, vis); - visit_fn_sig(sig, vis); - vis.visit_generics(generics); - visit_opt(body, |body| vis.visit_block(body)); - } - ItemKind::Mod(unsafety, mod_kind) => { - visit_unsafety(unsafety, vis); - match mod_kind { - ModKind::Loaded(items, _inline, ModSpans { inner_span, inject_use_span }) => { - vis.visit_span(inner_span); - vis.visit_span(inject_use_span); - items.flat_map_in_place(|item| vis.flat_map_item(item)); +pub fn noop_visit_item_kind(kind: &mut impl NoopVisitItemKind, vis: &mut impl MutVisitor) { + kind.noop_visit(vis) +} + +impl NoopVisitItemKind for ItemKind { + fn noop_visit(&mut self, vis: &mut impl MutVisitor) { + match self { + ItemKind::ExternCrate(_orig_name) => {} + ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree), + ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => { + vis.visit_ty(ty); + visit_opt(expr, |expr| vis.visit_expr(expr)); + } + ItemKind::Const(item) => { + visit_const_item(item, vis); + } + ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { + visit_defaultness(defaultness, vis); + visit_fn_sig(sig, vis); + vis.visit_generics(generics); + visit_opt(body, |body| vis.visit_block(body)); + } + ItemKind::Mod(unsafety, mod_kind) => { + visit_unsafety(unsafety, vis); + match mod_kind { + ModKind::Loaded(items, _inline, ModSpans { inner_span, inject_use_span }) => { + vis.visit_span(inner_span); + vis.visit_span(inject_use_span); + items.flat_map_in_place(|item| vis.flat_map_item(item)); + } + ModKind::Unloaded => {} } - ModKind::Unloaded => {} } - } - ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), - ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm), - ItemKind::TyAlias(box TyAlias { - defaultness, generics, where_clauses, bounds, ty, .. - }) => { - visit_defaultness(defaultness, vis); - vis.visit_generics(generics); - vis.visit_span(&mut where_clauses.before.span); - vis.visit_span(&mut where_clauses.after.span); - visit_bounds(bounds, vis); - visit_opt(ty, |ty| vis.visit_ty(ty)); - } - ItemKind::Enum(EnumDef { variants }, generics) => { - variants.flat_map_in_place(|variant| vis.flat_map_variant(variant)); - vis.visit_generics(generics); - } - ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => { - vis.visit_variant_data(variant_data); - vis.visit_generics(generics); - } - ItemKind::Impl(box Impl { - defaultness, - unsafety, - generics, - constness, - polarity, - of_trait, - self_ty, - items, - }) => { - visit_defaultness(defaultness, vis); - visit_unsafety(unsafety, vis); - vis.visit_generics(generics); - visit_constness(constness, vis); - visit_polarity(polarity, vis); - visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref)); - vis.visit_ty(self_ty); - items.flat_map_in_place(|item| vis.flat_map_impl_item(item)); - } - ItemKind::Trait(box Trait { unsafety, is_auto: _, generics, bounds, items }) => { - visit_unsafety(unsafety, vis); - vis.visit_generics(generics); - visit_bounds(bounds, vis); - items.flat_map_in_place(|item| vis.flat_map_trait_item(item)); - } - ItemKind::TraitAlias(generics, bounds) => { - vis.visit_generics(generics); - visit_bounds(bounds, vis); - } - ItemKind::MacCall(m) => vis.visit_mac_call(m), - ItemKind::MacroDef(def) => vis.visit_macro_def(def), - ItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => { - vis.visit_id(id); - vis.visit_qself(qself); - vis.visit_path(path); - if let Some(rename) = rename { - vis.visit_ident(rename); + ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), + ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm), + ItemKind::TyAlias(box TyAlias { + defaultness, + generics, + where_clauses, + bounds, + ty, + .. + }) => { + visit_defaultness(defaultness, vis); + vis.visit_generics(generics); + vis.visit_span(&mut where_clauses.before.span); + vis.visit_span(&mut where_clauses.after.span); + visit_bounds(bounds, vis); + visit_opt(ty, |ty| vis.visit_ty(ty)); } - if let Some(body) = body { - vis.visit_block(body); + ItemKind::Enum(EnumDef { variants }, generics) => { + variants.flat_map_in_place(|variant| vis.flat_map_variant(variant)); + vis.visit_generics(generics); + } + ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => { + vis.visit_variant_data(variant_data); + vis.visit_generics(generics); + } + ItemKind::Impl(box Impl { + defaultness, + unsafety, + generics, + constness, + polarity, + of_trait, + self_ty, + items, + }) => { + visit_defaultness(defaultness, vis); + visit_unsafety(unsafety, vis); + vis.visit_generics(generics); + visit_constness(constness, vis); + visit_polarity(polarity, vis); + visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref)); + vis.visit_ty(self_ty); + items.flat_map_in_place(|item| vis.flat_map_impl_item(item)); + } + ItemKind::Trait(box Trait { unsafety, is_auto: _, generics, bounds, items }) => { + visit_unsafety(unsafety, vis); + vis.visit_generics(generics); + visit_bounds(bounds, vis); + items.flat_map_in_place(|item| vis.flat_map_trait_item(item)); + } + ItemKind::TraitAlias(generics, bounds) => { + vis.visit_generics(generics); + visit_bounds(bounds, vis); + } + ItemKind::MacCall(m) => vis.visit_mac_call(m), + ItemKind::MacroDef(def) => vis.visit_macro_def(def), + ItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => { + vis.visit_id(id); + vis.visit_qself(qself); + vis.visit_path(path); + if let Some(rename) = rename { + vis.visit_ident(rename); + } + if let Some(body) = body { + vis.visit_block(body); + } } } } } -pub fn noop_flat_map_assoc_item( - mut item: P, - visitor: &mut T, -) -> SmallVec<[P; 1]> { - let Item { id, ident, vis, attrs, kind, span, tokens } = item.deref_mut(); - visitor.visit_id(id); - visitor.visit_ident(ident); - visitor.visit_vis(vis); - visit_attrs(attrs, visitor); - match kind { - AssocItemKind::Const(item) => { - visit_const_item(item, visitor); - } - AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visit_defaultness(defaultness, visitor); - visitor.visit_generics(generics); - visit_fn_sig(sig, visitor); - visit_opt(body, |body| visitor.visit_block(body)); - } - AssocItemKind::Type(box TyAlias { - defaultness, - generics, - where_clauses, - bounds, - ty, - .. - }) => { - visit_defaultness(defaultness, visitor); - visitor.visit_generics(generics); - visitor.visit_span(&mut where_clauses.before.span); - visitor.visit_span(&mut where_clauses.after.span); - visit_bounds(bounds, visitor); - visit_opt(ty, |ty| visitor.visit_ty(ty)); - } - AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac), - AssocItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => { - visitor.visit_id(id); - visitor.visit_qself(qself); - visitor.visit_path(path); - if let Some(rename) = rename { - visitor.visit_ident(rename); +impl NoopVisitItemKind for AssocItemKind { + fn noop_visit(&mut self, visitor: &mut impl MutVisitor) { + match self { + AssocItemKind::Const(item) => { + visit_const_item(item, visitor); } - if let Some(body) = body { - visitor.visit_block(body); + AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { + visit_defaultness(defaultness, visitor); + visitor.visit_generics(generics); + visit_fn_sig(sig, visitor); + visit_opt(body, |body| visitor.visit_block(body)); + } + AssocItemKind::Type(box TyAlias { + defaultness, + generics, + where_clauses, + bounds, + ty, + .. + }) => { + visit_defaultness(defaultness, visitor); + visitor.visit_generics(generics); + visitor.visit_span(&mut where_clauses.before.span); + visitor.visit_span(&mut where_clauses.after.span); + visit_bounds(bounds, visitor); + visit_opt(ty, |ty| visitor.visit_ty(ty)); + } + AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac), + AssocItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => { + visitor.visit_id(id); + visitor.visit_qself(qself); + visitor.visit_path(path); + if let Some(rename) = rename { + visitor.visit_ident(rename); + } + if let Some(body) = body { + visitor.visit_block(body); + } } } } - visitor.visit_span(span); - visit_lazy_tts(tokens, visitor); - smallvec![item] } fn visit_const_item( @@ -1241,62 +1243,52 @@ pub fn noop_visit_crate(krate: &mut Crate, vis: &mut T) { } // Mutates one item into possibly many items. -pub fn noop_flat_map_item( - mut item: P, - visitor: &mut T, -) -> SmallVec<[P; 1]> { +pub fn noop_flat_map_item( + mut item: P>, + visitor: &mut impl MutVisitor, +) -> SmallVec<[P>; 1]> { let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); visitor.visit_ident(ident); visit_attrs(attrs, visitor); visitor.visit_id(id); - visitor.visit_item_kind(kind); + kind.noop_visit(visitor); visitor.visit_vis(vis); visitor.visit_span(span); visit_lazy_tts(tokens, visitor); - smallvec![item] } -pub fn noop_flat_map_foreign_item( - mut item: P, - visitor: &mut T, -) -> SmallVec<[P; 1]> { - let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); - visitor.visit_id(id); - visitor.visit_ident(ident); - visitor.visit_vis(vis); - visit_attrs(attrs, visitor); - match kind { - ForeignItemKind::Static(ty, _, expr) => { - visitor.visit_ty(ty); - visit_opt(expr, |expr| visitor.visit_expr(expr)); +impl NoopVisitItemKind for ForeignItemKind { + fn noop_visit(&mut self, visitor: &mut impl MutVisitor) { + match self { + ForeignItemKind::Static(ty, _, expr) => { + visitor.visit_ty(ty); + visit_opt(expr, |expr| visitor.visit_expr(expr)); + } + ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { + visit_defaultness(defaultness, visitor); + visitor.visit_generics(generics); + visit_fn_sig(sig, visitor); + visit_opt(body, |body| visitor.visit_block(body)); + } + ForeignItemKind::TyAlias(box TyAlias { + defaultness, + generics, + where_clauses, + bounds, + ty, + .. + }) => { + visit_defaultness(defaultness, visitor); + visitor.visit_generics(generics); + visitor.visit_span(&mut where_clauses.before.span); + visitor.visit_span(&mut where_clauses.after.span); + visit_bounds(bounds, visitor); + visit_opt(ty, |ty| visitor.visit_ty(ty)); + } + ForeignItemKind::MacCall(mac) => visitor.visit_mac_call(mac), } - ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visit_defaultness(defaultness, visitor); - visitor.visit_generics(generics); - visit_fn_sig(sig, visitor); - visit_opt(body, |body| visitor.visit_block(body)); - } - ForeignItemKind::TyAlias(box TyAlias { - defaultness, - generics, - where_clauses, - bounds, - ty, - .. - }) => { - visit_defaultness(defaultness, visitor); - visitor.visit_generics(generics); - visitor.visit_span(&mut where_clauses.before.span); - visitor.visit_span(&mut where_clauses.after.span); - visit_bounds(bounds, visitor); - visit_opt(ty, |ty| visitor.visit_ty(ty)); - } - ForeignItemKind::MacCall(mac) => visitor.visit_mac_call(mac), } - visitor.visit_span(span); - visit_lazy_tts(tokens, visitor); - smallvec![item] } pub fn noop_visit_pat(pat: &mut P, vis: &mut T) { diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index d9740928f8d6..c4a7c8a4540a 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -102,6 +102,15 @@ pub enum LifetimeCtxt { GenericArg, } +pub trait WalkItemKind: Sized { + fn walk<'a, V: Visitor<'a>>( + &'a self, + item: &'a Item, + ctxt: AssocCtxt, + visitor: &mut V, + ) -> V::Result; +} + /// Each method of the `Visitor` trait is a hook to be potentially /// overridden. Each method's default implementation recursively visits /// the substructure of the input via the corresponding `walk` method; @@ -120,7 +129,7 @@ pub trait Visitor<'ast>: Sized { Self::Result::output() } fn visit_foreign_item(&mut self, i: &'ast ForeignItem) -> Self::Result { - walk_foreign_item(self, i) + walk_item(self, i) } fn visit_item(&mut self, i: &'ast Item) -> Self::Result { walk_item(self, i) @@ -312,87 +321,98 @@ pub fn walk_trait_ref<'a, V: Visitor<'a>>(visitor: &mut V, trait_ref: &'a TraitR visitor.visit_path(&trait_ref.path, trait_ref.ref_id) } -pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) -> V::Result { - try_visit!(visitor.visit_vis(&item.vis)); - try_visit!(visitor.visit_ident(item.ident)); - match &item.kind { - ItemKind::ExternCrate(_) => {} - ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, item.id, false)), - ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => { - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_expr, expr); - } - ItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => { - try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_expr, expr); - } - ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { - let kind = - FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref()); - try_visit!(visitor.visit_fn(kind, item.span, item.id)); - } - ItemKind::Mod(_unsafety, mod_kind) => match mod_kind { - ModKind::Loaded(items, _inline, _inner_span) => { - walk_list!(visitor, visit_item, items); +impl WalkItemKind for ItemKind { + fn walk<'a, V: Visitor<'a>>( + &'a self, + item: &'a Item, + _ctxt: AssocCtxt, + visitor: &mut V, + ) -> V::Result { + match self { + ItemKind::ExternCrate(_) => {} + ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, item.id, false)), + ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => { + try_visit!(visitor.visit_ty(ty)); + visit_opt!(visitor, visit_expr, expr); } - ModKind::Unloaded => {} - }, - ItemKind::ForeignMod(foreign_module) => { - walk_list!(visitor, visit_foreign_item, &foreign_module.items); - } - ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)), - ItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => { - try_visit!(visitor.visit_generics(generics)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - visit_opt!(visitor, visit_ty, ty); - } - ItemKind::Enum(enum_definition, generics) => { - try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_enum_def(enum_definition)); - } - ItemKind::Impl(box Impl { - defaultness: _, - unsafety: _, - generics, - constness: _, - polarity: _, - of_trait, - self_ty, - items, - }) => { - try_visit!(visitor.visit_generics(generics)); - visit_opt!(visitor, visit_trait_ref, of_trait); - try_visit!(visitor.visit_ty(self_ty)); - walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl); - } - ItemKind::Struct(struct_definition, generics) - | ItemKind::Union(struct_definition, generics) => { - try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_variant_data(struct_definition)); - } - ItemKind::Trait(box Trait { unsafety: _, is_auto: _, generics, bounds, items }) => { - try_visit!(visitor.visit_generics(generics)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits); - walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait); - } - ItemKind::TraitAlias(generics, bounds) => { - try_visit!(visitor.visit_generics(generics)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - } - ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)), - ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, item.id)), - ItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => { - if let Some(qself) = qself { - try_visit!(visitor.visit_ty(&qself.ty)); + ItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => { + try_visit!(visitor.visit_generics(generics)); + try_visit!(visitor.visit_ty(ty)); + visit_opt!(visitor, visit_expr, expr); + } + ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { + let kind = + FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref()); + try_visit!(visitor.visit_fn(kind, item.span, item.id)); + } + ItemKind::Mod(_unsafety, mod_kind) => match mod_kind { + ModKind::Loaded(items, _inline, _inner_span) => { + walk_list!(visitor, visit_item, items); + } + ModKind::Unloaded => {} + }, + ItemKind::ForeignMod(foreign_module) => { + walk_list!(visitor, visit_foreign_item, &foreign_module.items); + } + ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)), + ItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => { + try_visit!(visitor.visit_generics(generics)); + walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); + visit_opt!(visitor, visit_ty, ty); + } + ItemKind::Enum(enum_definition, generics) => { + try_visit!(visitor.visit_generics(generics)); + try_visit!(visitor.visit_enum_def(enum_definition)); + } + ItemKind::Impl(box Impl { + defaultness: _, + unsafety: _, + generics, + constness: _, + polarity: _, + of_trait, + self_ty, + items, + }) => { + try_visit!(visitor.visit_generics(generics)); + visit_opt!(visitor, visit_trait_ref, of_trait); + try_visit!(visitor.visit_ty(self_ty)); + walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl); + } + ItemKind::Struct(struct_definition, generics) + | ItemKind::Union(struct_definition, generics) => { + try_visit!(visitor.visit_generics(generics)); + try_visit!(visitor.visit_variant_data(struct_definition)); + } + ItemKind::Trait(box Trait { unsafety: _, is_auto: _, generics, bounds, items }) => { + try_visit!(visitor.visit_generics(generics)); + walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits); + walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait); + } + ItemKind::TraitAlias(generics, bounds) => { + try_visit!(visitor.visit_generics(generics)); + walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); + } + ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)), + ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, item.id)), + ItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => { + if let Some(qself) = qself { + try_visit!(visitor.visit_ty(&qself.ty)); + } + try_visit!(visitor.visit_path(path, *id)); + visit_opt!(visitor, visit_ident, *rename); + visit_opt!(visitor, visit_block, body); } - try_visit!(visitor.visit_path(path, *id)); - visit_opt!(visitor, visit_ident, *rename); - visit_opt!(visitor, visit_block, body); } + V::Result::output() } - walk_list!(visitor, visit_attribute, &item.attrs); - V::Result::output() +} + +pub fn walk_item<'a, V: Visitor<'a>>( + visitor: &mut V, + item: &'a Item, +) -> V::Result { + walk_assoc_item(visitor, item, AssocCtxt::Trait /*ignored*/) } pub fn walk_enum_def<'a, V: Visitor<'a>>( @@ -613,30 +633,34 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) -> V::Res V::Result::output() } -pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignItem) -> V::Result { - let &Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = item; - try_visit!(visitor.visit_vis(vis)); - try_visit!(visitor.visit_ident(ident)); - walk_list!(visitor, visit_attribute, attrs); - match kind { - ForeignItemKind::Static(ty, _, expr) => { - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_expr, expr); - } - ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { - let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref()); - try_visit!(visitor.visit_fn(kind, span, id)); - } - ForeignItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => { - try_visit!(visitor.visit_generics(generics)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - visit_opt!(visitor, visit_ty, ty); - } - ForeignItemKind::MacCall(mac) => { - try_visit!(visitor.visit_mac_call(mac)); +impl WalkItemKind for ForeignItemKind { + fn walk<'a, V: Visitor<'a>>( + &'a self, + item: &'a Item, + _ctxt: AssocCtxt, + visitor: &mut V, + ) -> V::Result { + let &Item { id, span, ident, ref vis, .. } = item; + match self { + ForeignItemKind::Static(ty, _, expr) => { + try_visit!(visitor.visit_ty(ty)); + visit_opt!(visitor, visit_expr, expr); + } + ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { + let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref()); + try_visit!(visitor.visit_fn(kind, span, id)); + } + ForeignItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => { + try_visit!(visitor.visit_generics(generics)); + walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); + visit_opt!(visitor, visit_ty, ty); + } + ForeignItemKind::MacCall(mac) => { + try_visit!(visitor.visit_mac_call(mac)); + } } + V::Result::output() } - V::Result::output() } pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) -> V::Result { @@ -756,42 +780,56 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu V::Result::output() } +impl WalkItemKind for AssocItemKind { + fn walk<'a, V: Visitor<'a>>( + &'a self, + item: &'a Item, + ctxt: AssocCtxt, + visitor: &mut V, + ) -> V::Result { + let &Item { id, span, ident, ref vis, .. } = item; + match self { + AssocItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => { + try_visit!(visitor.visit_generics(generics)); + try_visit!(visitor.visit_ty(ty)); + visit_opt!(visitor, visit_expr, expr); + } + AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { + let kind = + FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref()); + try_visit!(visitor.visit_fn(kind, span, id)); + } + AssocItemKind::Type(box TyAlias { generics, bounds, ty, .. }) => { + try_visit!(visitor.visit_generics(generics)); + walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); + visit_opt!(visitor, visit_ty, ty); + } + AssocItemKind::MacCall(mac) => { + try_visit!(visitor.visit_mac_call(mac)); + } + AssocItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => { + if let Some(qself) = qself { + try_visit!(visitor.visit_ty(&qself.ty)); + } + try_visit!(visitor.visit_path(path, *id)); + visit_opt!(visitor, visit_ident, *rename); + visit_opt!(visitor, visit_block, body); + } + } + V::Result::output() + } +} + pub fn walk_assoc_item<'a, V: Visitor<'a>>( visitor: &mut V, - item: &'a AssocItem, + item: &'a Item, ctxt: AssocCtxt, ) -> V::Result { - let &Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = item; + let &Item { id: _, span: _, ident, ref vis, ref attrs, ref kind, tokens: _ } = item; try_visit!(visitor.visit_vis(vis)); try_visit!(visitor.visit_ident(ident)); walk_list!(visitor, visit_attribute, attrs); - match kind { - AssocItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => { - try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_expr, expr); - } - AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { - let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref()); - try_visit!(visitor.visit_fn(kind, span, id)); - } - AssocItemKind::Type(box TyAlias { generics, bounds, ty, .. }) => { - try_visit!(visitor.visit_generics(generics)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - visit_opt!(visitor, visit_ty, ty); - } - AssocItemKind::MacCall(mac) => { - try_visit!(visitor.visit_mac_call(mac)); - } - AssocItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => { - if let Some(qself) = qself { - try_visit!(visitor.visit_ty(&qself.ty)); - } - try_visit!(visitor.visit_path(path, *id)); - visit_opt!(visitor, visit_ident, *rename); - visit_opt!(visitor, visit_block, body); - } - } + try_visit!(kind.walk(item, ctxt, visitor)); V::Result::output() } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c5b5acf7f32d..61bc7f268cf4 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -394,7 +394,7 @@ fn index_crate<'a>( let def_id = self.node_id_to_def_id[&item.id]; *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::ForeignItem(item); - visit::walk_foreign_item(self, item); + visit::walk_item(self, item); } } } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 4e3d560ce898..1fb410253d1e 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1192,7 +1192,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ForeignItemKind::MacCall(..) => {} } - visit::walk_foreign_item(self, fi) + visit::walk_item(self, fi) } // Mirrors `visit::walk_generic_args`, but tracks relevant state. diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index d86196cbaa9a..e0000e354ca5 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -319,7 +319,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::ForeignItemKind::MacCall(..) => {} } - visit::walk_foreign_item(self, i) + visit::walk_item(self, i) } fn visit_ty(&mut self, ty: &'a ast::Ty) { diff --git a/compiler/rustc_ast_passes/src/node_count.rs b/compiler/rustc_ast_passes/src/node_count.rs index fa42f87786de..2128acba0bab 100644 --- a/compiler/rustc_ast_passes/src/node_count.rs +++ b/compiler/rustc_ast_passes/src/node_count.rs @@ -21,7 +21,7 @@ impl<'ast> Visitor<'ast> for NodeCounter { } fn visit_foreign_item(&mut self, i: &ForeignItem) { self.count += 1; - walk_foreign_item(self, i) + walk_item(self, i) } fn visit_item(&mut self, i: &Item) { self.count += 1; diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index 93f7d09546b7..c192b188aa66 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -246,18 +246,18 @@ impl MutVisitor for CfgEval<'_, '_> { } fn flat_map_impl_item(&mut self, item: P) -> SmallVec<[P; 1]> { - mut_visit::noop_flat_map_assoc_item(configure!(self, item), self) + mut_visit::noop_flat_map_item(configure!(self, item), self) } fn flat_map_trait_item(&mut self, item: P) -> SmallVec<[P; 1]> { - mut_visit::noop_flat_map_assoc_item(configure!(self, item), self) + mut_visit::noop_flat_map_item(configure!(self, item), self) } fn flat_map_foreign_item( &mut self, foreign_item: P, ) -> SmallVec<[P; 1]> { - mut_visit::noop_flat_map_foreign_item(configure!(self, foreign_item), self) + mut_visit::noop_flat_map_item(configure!(self, foreign_item), self) } fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> { diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 6029caa965c0..d1f58610c4ea 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1218,7 +1218,7 @@ impl InvocationCollectorNode for AstNodeWrapper, TraitItemTag> fragment.make_trait_items() } fn noop_flat_map(self, visitor: &mut V) -> Self::OutputTy { - noop_flat_map_assoc_item(self.wrapped, visitor) + noop_flat_map_item(self.wrapped, visitor) } fn is_mac_call(&self) -> bool { matches!(self.wrapped.kind, AssocItemKind::MacCall(..)) @@ -1243,7 +1243,7 @@ impl InvocationCollectorNode for AstNodeWrapper, ImplItemTag> fragment.make_impl_items() } fn noop_flat_map(self, visitor: &mut V) -> Self::OutputTy { - noop_flat_map_assoc_item(self.wrapped, visitor) + noop_flat_map_item(self.wrapped, visitor) } fn is_mac_call(&self) -> bool { matches!(self.wrapped.kind, AssocItemKind::MacCall(..)) @@ -1266,7 +1266,7 @@ impl InvocationCollectorNode for P { fragment.make_foreign_items() } fn noop_flat_map(self, visitor: &mut V) -> Self::OutputTy { - noop_flat_map_foreign_item(self, visitor) + noop_flat_map_item(self, visitor) } fn is_mac_call(&self) -> bool { matches!(self.kind, ForeignItemKind::MacCall(..)) diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 2c4187031cac..581d71875bd0 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -271,14 +271,14 @@ impl MutVisitor for PlaceholderExpander { fn flat_map_trait_item(&mut self, item: P) -> SmallVec<[P; 1]> { match item.kind { ast::AssocItemKind::MacCall(_) => self.remove(item.id).make_trait_items(), - _ => noop_flat_map_assoc_item(item, self), + _ => noop_flat_map_item(item, self), } } fn flat_map_impl_item(&mut self, item: P) -> SmallVec<[P; 1]> { match item.kind { ast::AssocItemKind::MacCall(_) => self.remove(item.id).make_impl_items(), - _ => noop_flat_map_assoc_item(item, self), + _ => noop_flat_map_item(item, self), } } @@ -288,7 +288,7 @@ impl MutVisitor for PlaceholderExpander { ) -> SmallVec<[P; 1]> { match item.kind { ast::ForeignItemKind::MacCall(_) => self.remove(item.id).make_foreign_items(), - _ => noop_flat_map_foreign_item(item, self), + _ => noop_flat_map_item(item, self), } } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 9fae32a49c78..3f627baf7704 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -99,7 +99,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> fn visit_foreign_item(&mut self, it: &'a ast::ForeignItem) { self.with_lint_attrs(it.id, &it.attrs, |cx| { - ast_visit::walk_foreign_item(cx, it); + ast_visit::walk_item(cx, it); }) } diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 49408c5618b0..d7664d1c1fff 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -498,7 +498,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { (self, i, i.kind, Id::None, ast, ForeignItem, ForeignItemKind), [Static, Fn, TyAlias, MacCall] ); - ast_visit::walk_foreign_item(self, i) + ast_visit::walk_item(self, i) } fn visit_item(&mut self, i: &'v ast::Item) { diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 1b6387acf71e..3c845e10b3c7 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1339,7 +1339,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { } self.build_reduced_graph_for_foreign_item(foreign_item); - visit::walk_foreign_item(self, foreign_item); + visit::walk_item(self, foreign_item); } fn visit_block(&mut self, block: &'b Block) { diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index bef95aca0d1c..840b5213fd7b 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -224,7 +224,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { let def = self.create_def(fi.id, fi.ident.name, def_kind, fi.span); - self.with_parent(def, |this| visit::walk_foreign_item(this, fi)); + self.with_parent(def, |this| visit::walk_item(this, fi)); } fn visit_variant(&mut self, v: &'a Variant) { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 292af43b602e..6c870ddfd227 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -886,7 +886,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, kind: LifetimeBinderKind::Item, span: generics.span, }, - |this| visit::walk_foreign_item(this, foreign_item), + |this| visit::walk_item(this, foreign_item), ); } ForeignItemKind::Fn(box Fn { ref generics, .. }) => { @@ -898,13 +898,11 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, kind: LifetimeBinderKind::Function, span: generics.span, }, - |this| visit::walk_foreign_item(this, foreign_item), + |this| visit::walk_item(this, foreign_item), ); } ForeignItemKind::Static(..) => { - self.with_static_rib(def_kind, |this| { - visit::walk_foreign_item(this, foreign_item); - }); + self.with_static_rib(def_kind, |this| visit::walk_item(this, foreign_item)) } ForeignItemKind::MacCall(..) => { panic!("unexpanded macro in resolve!") diff --git a/src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr b/src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr index 23d5dcd3a8da..aef6c3914526 100644 --- a/src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr +++ b/src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr @@ -1,35 +1,11 @@ -error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:10:9 - | -LL | /// - First String: - | ^^^^ help: consider using four spaces per tab - | - = note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]` - -error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:11:9 - | -LL | /// - needs to be inside here - | ^^^^^^^^ help: consider using four spaces per tab - -error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:14:9 - | -LL | /// - Second String: - | ^^^^ help: consider using four spaces per tab - -error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:15:9 - | -LL | /// - needs to be inside here - | ^^^^^^^^ help: consider using four spaces per tab - error: using tabs in doc comments is not recommended --> tests/ui/tabs_in_doc_comments.rs:6:5 | LL | /// - first one | ^^^^ help: consider using four spaces per tab + | + = note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]` error: using tabs in doc comments is not recommended --> tests/ui/tabs_in_doc_comments.rs:6:13 @@ -49,5 +25,29 @@ error: using tabs in doc comments is not recommended LL | /// - second one | ^^^^ help: consider using four spaces per tab +error: using tabs in doc comments is not recommended + --> tests/ui/tabs_in_doc_comments.rs:10:9 + | +LL | /// - First String: + | ^^^^ help: consider using four spaces per tab + +error: using tabs in doc comments is not recommended + --> tests/ui/tabs_in_doc_comments.rs:11:9 + | +LL | /// - needs to be inside here + | ^^^^^^^^ help: consider using four spaces per tab + +error: using tabs in doc comments is not recommended + --> tests/ui/tabs_in_doc_comments.rs:14:9 + | +LL | /// - Second String: + | ^^^^ help: consider using four spaces per tab + +error: using tabs in doc comments is not recommended + --> tests/ui/tabs_in_doc_comments.rs:15:9 + | +LL | /// - needs to be inside here + | ^^^^^^^^ help: consider using four spaces per tab + error: aborting due to 8 previous errors diff --git a/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr b/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr index 815013733a98..9bab366f7fef 100644 --- a/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr +++ b/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr @@ -1,3 +1,13 @@ +error[E0658]: the `#[optimize]` attribute is an experimental feature + --> $DIR/feature-gate-optimize_attribute.rs:4:1 + | +LL | #[optimize(size)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #54882 for more information + = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0658]: the `#[optimize]` attribute is an experimental feature --> $DIR/feature-gate-optimize_attribute.rs:7:1 | @@ -28,16 +38,6 @@ LL | #[optimize(banana)] = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: the `#[optimize]` attribute is an experimental feature - --> $DIR/feature-gate-optimize_attribute.rs:4:1 - | -LL | #[optimize(size)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #54882 for more information - = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - error[E0658]: the `#[optimize]` attribute is an experimental feature --> $DIR/feature-gate-optimize_attribute.rs:2:1 | diff --git a/tests/ui/feature-gates/issue-43106-gating-of-stable.stderr b/tests/ui/feature-gates/issue-43106-gating-of-stable.stderr index 677fef3a926b..e4cc088e2cd3 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-stable.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-stable.stderr @@ -1,3 +1,9 @@ +error[E0734]: stability attributes may not be used outside of the standard library + --> $DIR/issue-43106-gating-of-stable.rs:10:1 + | +LL | #[stable()] + | ^^^^^^^^^^^ + error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-stable.rs:14:9 | @@ -28,12 +34,6 @@ error[E0734]: stability attributes may not be used outside of the standard libra LL | #[stable()] | ^^^^^^^^^^^ -error[E0734]: stability attributes may not be used outside of the standard library - --> $DIR/issue-43106-gating-of-stable.rs:10:1 - | -LL | #[stable()] - | ^^^^^^^^^^^ - error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-stable.rs:7:1 | diff --git a/tests/ui/feature-gates/issue-43106-gating-of-unstable.stderr b/tests/ui/feature-gates/issue-43106-gating-of-unstable.stderr index a2f361878c6d..f7c6e631cd17 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-unstable.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-unstable.stderr @@ -1,3 +1,9 @@ +error[E0734]: stability attributes may not be used outside of the standard library + --> $DIR/issue-43106-gating-of-unstable.rs:10:1 + | +LL | #[unstable()] + | ^^^^^^^^^^^^^ + error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-unstable.rs:14:9 | @@ -28,12 +34,6 @@ error[E0734]: stability attributes may not be used outside of the standard libra LL | #[unstable()] | ^^^^^^^^^^^^^ -error[E0734]: stability attributes may not be used outside of the standard library - --> $DIR/issue-43106-gating-of-unstable.rs:10:1 - | -LL | #[unstable()] - | ^^^^^^^^^^^^^ - error[E0734]: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-unstable.rs:7:1 | From ec9ddc7b7af7f5b277cf06960bee9a20c3de8689 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 24 Apr 2024 20:31:51 +0300 Subject: [PATCH 060/279] ast: Generalize item kind visiting And avoid duplicating logic for visiting `Item`s with different kinds (regular, associated, foreign). --- tests/ui/tabs_in_doc_comments.stderr | 54 ++++++++++++++-------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/tests/ui/tabs_in_doc_comments.stderr b/tests/ui/tabs_in_doc_comments.stderr index 23d5dcd3a8da..aef6c3914526 100644 --- a/tests/ui/tabs_in_doc_comments.stderr +++ b/tests/ui/tabs_in_doc_comments.stderr @@ -1,35 +1,11 @@ -error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:10:9 - | -LL | /// - First String: - | ^^^^ help: consider using four spaces per tab - | - = note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]` - -error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:11:9 - | -LL | /// - needs to be inside here - | ^^^^^^^^ help: consider using four spaces per tab - -error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:14:9 - | -LL | /// - Second String: - | ^^^^ help: consider using four spaces per tab - -error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:15:9 - | -LL | /// - needs to be inside here - | ^^^^^^^^ help: consider using four spaces per tab - error: using tabs in doc comments is not recommended --> tests/ui/tabs_in_doc_comments.rs:6:5 | LL | /// - first one | ^^^^ help: consider using four spaces per tab + | + = note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]` error: using tabs in doc comments is not recommended --> tests/ui/tabs_in_doc_comments.rs:6:13 @@ -49,5 +25,29 @@ error: using tabs in doc comments is not recommended LL | /// - second one | ^^^^ help: consider using four spaces per tab +error: using tabs in doc comments is not recommended + --> tests/ui/tabs_in_doc_comments.rs:10:9 + | +LL | /// - First String: + | ^^^^ help: consider using four spaces per tab + +error: using tabs in doc comments is not recommended + --> tests/ui/tabs_in_doc_comments.rs:11:9 + | +LL | /// - needs to be inside here + | ^^^^^^^^ help: consider using four spaces per tab + +error: using tabs in doc comments is not recommended + --> tests/ui/tabs_in_doc_comments.rs:14:9 + | +LL | /// - Second String: + | ^^^^ help: consider using four spaces per tab + +error: using tabs in doc comments is not recommended + --> tests/ui/tabs_in_doc_comments.rs:15:9 + | +LL | /// - needs to be inside here + | ^^^^^^^^ help: consider using four spaces per tab + error: aborting due to 8 previous errors From 7517a4f882083a46593417560cdd19c10c3fc5cf Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 25 Apr 2024 22:50:06 +0300 Subject: [PATCH 061/279] ast: Visit item components in "natural" order --- compiler/rustc_ast/src/mut_visit.rs | 6 +++--- compiler/rustc_ast/src/visit.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 2ff8098035d7..fc445600e77b 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1248,11 +1248,11 @@ pub fn noop_flat_map_item( visitor: &mut impl MutVisitor, ) -> SmallVec<[P>; 1]> { let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); - visitor.visit_ident(ident); - visit_attrs(attrs, visitor); visitor.visit_id(id); - kind.noop_visit(visitor); + visit_attrs(attrs, visitor); visitor.visit_vis(vis); + visitor.visit_ident(ident); + kind.noop_visit(visitor); visitor.visit_span(span); visit_lazy_tts(tokens, visitor); smallvec![item] diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index c4a7c8a4540a..a0ada9a7788d 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -826,9 +826,9 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>( ctxt: AssocCtxt, ) -> V::Result { let &Item { id: _, span: _, ident, ref vis, ref attrs, ref kind, tokens: _ } = item; + walk_list!(visitor, visit_attribute, attrs); try_visit!(visitor.visit_vis(vis)); try_visit!(visitor.visit_ident(ident)); - walk_list!(visitor, visit_attribute, attrs); try_visit!(kind.walk(item, ctxt, visitor)); V::Result::output() } From b64f687cb01641c7e7a2d7b951f2e2d9c5044741 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 25 Apr 2024 20:19:01 +0000 Subject: [PATCH 062/279] use `EagerResolver` --- compiler/rustc_trait_selection/src/solve/inspect/analyse.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index dbded4cbd37b..f137780c536d 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -11,6 +11,7 @@ use rustc_ast_ir::try_visit; use rustc_ast_ir::visit::VisitorResult; +use rustc_infer::infer::resolve::EagerResolver; use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; use rustc_middle::infer::unify_key::ConstVariableOrigin; @@ -19,6 +20,7 @@ use rustc_middle::traits::solve::{inspect, QueryResult}; use rustc_middle::traits::solve::{Certainty, Goal}; use rustc_middle::traits::ObligationCause; use rustc_middle::ty; +use rustc_middle::ty::TypeFoldable; use rustc_span::Span; use crate::solve::eval_ctxt::canonical; @@ -254,7 +256,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { infcx, depth, orig_values, - goal: infcx.resolve_vars_if_possible(root.uncanonicalized_goal), + goal: root.uncanonicalized_goal.fold_with(&mut EagerResolver::new(infcx)), evaluation: root, }, inspect::GoalEvaluationKind::Nested { .. } => unreachable!(), From 146f63782604058e31a81f62dd30d9671738398f Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 25 Apr 2024 20:21:38 +0000 Subject: [PATCH 063/279] add triage bot mentions --- triagebot.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 903569bf4454..499ba6e470cd 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -529,6 +529,10 @@ cc = ["@compiler-errors", "@lcnr"] message = "changes to the core type system" cc = ["@compiler-errors", "@lcnr"] +[mentions."compiler/rustc_hir_analysis/src/fn_ctxt/inspect_obligations.rs"] +message = "changes to `inspect_obligations.rs`" +cc = ["@compiler-errors", "@lcnr"] + [mentions."compiler/rustc_middle/src/mir/interpret"] message = "Some changes occurred to the CTFE / Miri engine" cc = ["@rust-lang/miri"] From e2d2b1c6987869ed2eb13f16cb91e560c295cb57 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 25 Apr 2024 15:13:53 +1000 Subject: [PATCH 064/279] Introduce `DeriveResolution`. Making this a proper struct, and giving its fields names, makes things easier to understand. --- compiler/rustc_builtin_macros/src/derive.rs | 19 +++++++++++++------ compiler/rustc_expand/src/base.rs | 11 ++++++++--- compiler/rustc_expand/src/expand.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 4 ++-- compiler/rustc_resolve/src/macros.rs | 16 ++++++++-------- 5 files changed, 32 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index ca03941f9509..d14858e5c1db 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -3,7 +3,9 @@ use crate::errors; use rustc_ast as ast; use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind}; -use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier}; +use rustc_expand::base::{ + Annotatable, DeriveResolution, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier, +}; use rustc_feature::AttributeTemplate; use rustc_parse::validate_attr; use rustc_session::Session; @@ -60,7 +62,12 @@ impl MultiItemModifier for Expander { report_path_args(sess, meta); meta.path.clone() }) - .map(|path| (path, dummy_annotatable(), None, self.is_const)) + .map(|path| DeriveResolution { + path, + item: dummy_annotatable(), + exts: None, + is_const: self.is_const, + }) .collect() } _ => vec![], @@ -69,15 +76,15 @@ impl MultiItemModifier for Expander { // Do not configure or clone items unless necessary. match &mut resolutions[..] { [] => {} - [(_, first_item, ..), others @ ..] => { - *first_item = cfg_eval( + [first, others @ ..] => { + first.item = cfg_eval( sess, features, item.clone(), ecx.current_expansion.lint_node_id, ); - for (_, item, _, _) in others { - *item = first_item.clone(); + for other in others { + other.item = first.item.clone(); } } } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index b25dd8fe67b7..d75c2530710a 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -968,7 +968,12 @@ impl SyntaxExtension { /// Error type that denotes indeterminacy. pub struct Indeterminate; -pub type DeriveResolutions = Vec<(ast::Path, Annotatable, Option>, bool)>; +pub struct DeriveResolution { + pub path: ast::Path, + pub item: Annotatable, + pub exts: Option>, + pub is_const: bool, +} pub trait ResolverExpand { fn next_node_id(&mut self) -> NodeId; @@ -1011,11 +1016,11 @@ pub trait ResolverExpand { &mut self, expn_id: LocalExpnId, force: bool, - derive_paths: &dyn Fn() -> DeriveResolutions, + derive_paths: &dyn Fn() -> Vec, ) -> Result<(), Indeterminate>; /// Take resolutions for paths inside the `#[derive(...)]` attribute with the given `ExpnId` /// back from resolver. - fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option; + fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option>; /// Path resolution logic for `#[cfg_accessible(path)]`. fn cfg_accessible( &mut self, diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 6029caa965c0..909197d90b66 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -482,7 +482,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { derive_invocations.reserve(derives.len()); derives .into_iter() - .map(|(path, item, _exts, is_const)| { + .map(|DeriveResolution { path, item, exts: _, is_const }| { // FIXME: Consider using the derive resolutions (`_exts`) // instead of enqueuing the derives to be resolved again later. let expn_id = LocalExpnId::fresh_empty(); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b8221d9d7f9f..aed85a34a9de 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -38,7 +38,7 @@ use rustc_data_structures::intern::Interned; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{FreezeReadGuard, Lrc}; use rustc_errors::{Applicability, Diag, ErrCode}; -use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind}; +use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind}; use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::NonMacroAttrKind; @@ -959,7 +959,7 @@ enum BuiltinMacroState { } struct DeriveData { - resolutions: DeriveResolutions, + resolutions: Vec, helper_attrs: Vec<(usize, Ident)>, has_derive_copy: bool, } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 2a23ed71753f..82e41b6c3143 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -15,7 +15,7 @@ use rustc_attr::StabilityLevel; use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, StashKey}; -use rustc_expand::base::{Annotatable, DeriveResolutions, Indeterminate, ResolverExpand}; +use rustc_expand::base::{Annotatable, DeriveResolution, Indeterminate, ResolverExpand}; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::compile_declarative_macro; use rustc_expand::expand::{AstFragment, Invocation, InvocationKind, SupportsMacroExpansion}; @@ -344,7 +344,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> { &mut self, expn_id: LocalExpnId, force: bool, - derive_paths: &dyn Fn() -> DeriveResolutions, + derive_paths: &dyn Fn() -> Vec, ) -> Result<(), Indeterminate> { // Block expansion of the container until we resolve all derives in it. // This is required for two reasons: @@ -360,11 +360,11 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> { has_derive_copy: false, }); let parent_scope = self.invocation_parent_scopes[&expn_id]; - for (i, (path, _, opt_ext, _)) in entry.resolutions.iter_mut().enumerate() { - if opt_ext.is_none() { - *opt_ext = Some( + for (i, resolution) in entry.resolutions.iter_mut().enumerate() { + if resolution.exts.is_none() { + resolution.exts = Some( match self.resolve_macro_path( - path, + &resolution.path, Some(MacroKind::Derive), &parent_scope, true, @@ -372,7 +372,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> { ) { Ok((Some(ext), _)) => { if !ext.helper_attrs.is_empty() { - let last_seg = path.segments.last().unwrap(); + let last_seg = resolution.path.segments.last().unwrap(); let span = last_seg.ident.span.normalize_to_macros_2_0(); entry.helper_attrs.extend( ext.helper_attrs @@ -416,7 +416,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> { Ok(()) } - fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option { + fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option> { self.derive_data.remove(&expn_id).map(|data| data.resolutions) } From 8dc84fa7d17980424b22909207056214663d0526 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 26 Apr 2024 08:44:23 +1000 Subject: [PATCH 065/279] Move some functions from `rustc_expand` to `rustc_builtin_macros`. These functions are only used in `rustc_builtin_macros`, so it makes sense for them to live there. This allows them to be changed from `pub` to `pub(crate)`. --- compiler/rustc_builtin_macros/messages.ftl | 6 + compiler/rustc_builtin_macros/src/asm.rs | 4 +- .../rustc_builtin_macros/src/compile_error.rs | 2 +- compiler/rustc_builtin_macros/src/concat.rs | 5 +- .../rustc_builtin_macros/src/concat_bytes.rs | 5 +- compiler/rustc_builtin_macros/src/env.rs | 5 +- compiler/rustc_builtin_macros/src/errors.rs | 23 +++ compiler/rustc_builtin_macros/src/format.rs | 9 +- compiler/rustc_builtin_macros/src/lib.rs | 2 +- .../rustc_builtin_macros/src/source_util.rs | 8 +- compiler/rustc_builtin_macros/src/util.rs | 188 +++++++++++++++++- compiler/rustc_expand/messages.ftl | 9 - compiler/rustc_expand/src/base.rs | 182 +---------------- compiler/rustc_expand/src/errors.rs | 23 --- 14 files changed, 234 insertions(+), 237 deletions(-) diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 2a5bc58af3b3..0f1589903193 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -118,6 +118,8 @@ builtin_macros_env_not_unicode = environment variable `{$var}` is not a valid Un builtin_macros_env_takes_args = `env!()` takes 1 or 2 arguments +builtin_macros_expected_comma_in_list = expected token: `,` + builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern builtin_macros_expected_register_class_or_explicit_register = expected register class or explicit register @@ -219,12 +221,16 @@ builtin_macros_non_exhaustive_default = default variant must be exhaustive builtin_macros_non_unit_default = the `#[default]` attribute may only be used on unit enum variants .help = consider a manual implementation of `Default` +builtin_macros_only_one_argument = {$name} takes 1 argument + builtin_macros_proc_macro = `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]` builtin_macros_requires_cfg_pattern = macro requires a cfg-pattern as an argument .label = cfg-pattern required +builtin_macros_takes_no_arguments = {$name} takes no arguments + builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests .label = `{$kind}` because of this diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 137ac4415792..49b1b8cf9926 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -1,3 +1,5 @@ +use crate::errors; +use crate::util::expr_to_spanned_string; use ast::token::IdentIsRaw; use rustc_ast as ast; use rustc_ast::ptr::P; @@ -16,8 +18,6 @@ use rustc_span::{ErrorGuaranteed, InnerSpan, Span}; use rustc_target::asm::InlineAsmArch; use smallvec::smallvec; -use crate::errors; - pub struct AsmArgs { pub templates: Vec>, pub operands: Vec<(ast::InlineAsmOperand, Span)>, diff --git a/compiler/rustc_builtin_macros/src/compile_error.rs b/compiler/rustc_builtin_macros/src/compile_error.rs index 2f2a87fc9aa0..833e9cb5d75a 100644 --- a/compiler/rustc_builtin_macros/src/compile_error.rs +++ b/compiler/rustc_builtin_macros/src/compile_error.rs @@ -1,7 +1,7 @@ // The compiler code necessary to support the compile_error! extension. +use crate::util::get_single_str_from_tts; use rustc_ast::tokenstream::TokenStream; -use rustc_expand::base::get_single_str_from_tts; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult}; use rustc_span::Span; diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs index 93a7ac05a9be..125f4bc6dc4a 100644 --- a/compiler/rustc_builtin_macros/src/concat.rs +++ b/compiler/rustc_builtin_macros/src/concat.rs @@ -1,12 +1,11 @@ +use crate::errors; +use crate::util::get_exprs_from_tts; use rustc_ast::tokenstream::TokenStream; use rustc_ast::{ExprKind, LitKind, UnOp}; -use rustc_expand::base::get_exprs_from_tts; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult}; use rustc_session::errors::report_lit_error; use rustc_span::symbol::Symbol; -use crate::errors; - pub fn expand_concat( cx: &mut ExtCtxt<'_>, sp: rustc_span::Span, diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs index 45fec2945788..f9d3f4a14258 100644 --- a/compiler/rustc_builtin_macros/src/concat_bytes.rs +++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs @@ -1,11 +1,10 @@ +use crate::errors; +use crate::util::get_exprs_from_tts; use rustc_ast::{ptr::P, token, tokenstream::TokenStream, ExprKind, LitIntType, LitKind, UintTy}; -use rustc_expand::base::get_exprs_from_tts; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult}; use rustc_session::errors::report_lit_error; use rustc_span::{ErrorGuaranteed, Span}; -use crate::errors; - /// Emits errors for literal expressions that are invalid inside and outside of an array. fn invalid_type_err( cx: &ExtCtxt<'_>, diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index 938730459437..3903c77b6696 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -3,10 +3,11 @@ // interface. // +use crate::errors; +use crate::util::{expr_to_string, get_exprs_from_tts, get_single_str_from_tts}; use rustc_ast::token::{self, LitKind}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::{AstDeref, ExprKind, GenericArg, Mutability}; -use rustc_expand::base::{expr_to_string, get_exprs_from_tts, get_single_str_from_tts}; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; @@ -14,8 +15,6 @@ use std::env; use std::env::VarError; use thin_vec::thin_vec; -use crate::errors; - fn lookup_env<'cx>(cx: &'cx ExtCtxt<'_>, var: Symbol) -> Result { let var = var.as_str(); if let Some(value) = cx.sess.opts.logical_env.get(var) { diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 6b6647ef085c..055ff79a8ad3 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -842,3 +842,26 @@ pub(crate) struct ExpectedRegisterClassOrExplicitRegister { #[primary_span] pub(crate) span: Span, } + +#[derive(Diagnostic)] +#[diag(builtin_macros_expected_comma_in_list)] +pub(crate) struct ExpectedCommaInList { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_only_one_argument)] +pub(crate) struct OnlyOneArgument<'a> { + #[primary_span] + pub span: Span, + pub name: &'a str, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_takes_no_arguments)] +pub(crate) struct TakesNoArguments<'a> { + #[primary_span] + pub span: Span, + pub name: &'a str, +} diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 51d6058a744f..3f44096714c0 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -1,3 +1,5 @@ +use crate::errors; +use crate::util::expr_to_spanned_string; use parse::Position::ArgumentNamed; use rustc_ast::ptr::P; use rustc_ast::tokenstream::TokenStream; @@ -10,14 +12,13 @@ use rustc_ast::{ use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, Diag, MultiSpan, PResult, SingleLabelManySpans}; use rustc_expand::base::*; +use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY; +use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiag, LintId}; use rustc_parse::parser::Recovered; use rustc_parse_format as parse; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{BytePos, ErrorGuaranteed, InnerSpan, Span}; -use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY; -use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiag, LintId}; - // The format_args!() macro is expanded in three steps: // 1. First, `parse_args` will parse the `(literal, arg, arg, name=arg, name=arg)` syntax, // but doesn't parse the template (the literal) itself. @@ -38,8 +39,6 @@ enum PositionUsedAs { } use PositionUsedAs::*; -use crate::errors; - #[derive(Debug)] struct MacroInput { fmtstr: P, diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 56a72432689d..7c7b9c2d65fb 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -50,13 +50,13 @@ mod pattern_type; mod source_util; mod test; mod trace_macros; -mod util; pub mod asm; pub mod cmdline_attrs; pub mod proc_macro_harness; pub mod standard_library_imports; pub mod test_harness; +pub mod util; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index c79ae716806c..033c7446b266 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -1,3 +1,6 @@ +use crate::util::{ + check_zero_tts, get_single_str_from_tts, get_single_str_spanned_from_tts, parse_expr, +}; use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_ast::token; @@ -5,11 +8,8 @@ use rustc_ast::tokenstream::TokenStream; use rustc_ast_pretty::pprust; use rustc_data_structures::sync::Lrc; use rustc_expand::base::{ - check_zero_tts, get_single_str_from_tts, get_single_str_spanned_from_tts, parse_expr, - resolve_path, + resolve_path, DummyResult, ExpandResult, ExtCtxt, MacEager, MacResult, MacroExpanderResult, }; -use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt}; -use rustc_expand::base::{MacEager, MacResult, MacroExpanderResult}; use rustc_expand::module::DirOwnership; use rustc_parse::new_parser_from_file; use rustc_parse::parser::{ForceCollect, Parser}; diff --git a/compiler/rustc_builtin_macros/src/util.rs b/compiler/rustc_builtin_macros/src/util.rs index ad6b09ba5745..49687c6a0ade 100644 --- a/compiler/rustc_builtin_macros/src/util.rs +++ b/compiler/rustc_builtin_macros/src/util.rs @@ -1,9 +1,14 @@ -use rustc_ast::{attr, AttrStyle, Attribute, MetaItem}; -use rustc_expand::base::{Annotatable, ExtCtxt}; +use crate::errors; +use rustc_ast::tokenstream::TokenStream; +use rustc_ast::{self as ast, attr, ptr::P, token, AttrStyle, Attribute, MetaItem}; +use rustc_errors::{Applicability, Diag, ErrorGuaranteed}; +use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt}; +use rustc_expand::expand::AstFragment; use rustc_feature::AttributeTemplate; use rustc_lint_defs::builtin::DUPLICATE_MACRO_ATTRIBUTES; -use rustc_parse::validate_attr; -use rustc_span::Symbol; +use rustc_parse::{parser, validate_attr}; +use rustc_session::errors::report_lit_error; +use rustc_span::{BytePos, Span, Symbol}; pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, name: Symbol) { // All the built-in macro attributes are "words" at the moment. @@ -46,3 +51,178 @@ pub fn warn_on_duplicate_attribute(ecx: &ExtCtxt<'_>, item: &Annotatable, name: } } } + +/// `Ok` represents successfully retrieving the string literal at the correct +/// position, e.g., `println("abc")`. +type ExprToSpannedStringResult<'a> = Result<(Symbol, ast::StrStyle, Span), UnexpectedExprKind<'a>>; + +/// - `Ok` is returned when the conversion to a string literal is unsuccessful, +/// but another type of expression is obtained instead. +/// - `Err` is returned when the conversion process fails. +type UnexpectedExprKind<'a> = Result<(Diag<'a>, bool /* has_suggestions */), ErrorGuaranteed>; + +/// Extracts a string literal from the macro expanded version of `expr`, +/// returning a diagnostic error of `err_msg` if `expr` is not a string literal. +/// The returned bool indicates whether an applicable suggestion has already been +/// added to the diagnostic to avoid emitting multiple suggestions. `Err(Err(ErrorGuaranteed))` +/// indicates that an ast error was encountered. +// FIXME(Nilstrieb) Make this function setup translatable +#[allow(rustc::untranslatable_diagnostic)] +pub(crate) fn expr_to_spanned_string<'a>( + cx: &'a mut ExtCtxt<'_>, + expr: P, + err_msg: &'static str, +) -> ExpandResult, ()> { + if !cx.force_mode + && let ast::ExprKind::MacCall(m) = &expr.kind + && cx.resolver.macro_accessible(cx.current_expansion.id, &m.path).is_err() + { + return ExpandResult::Retry(()); + } + + // Perform eager expansion on the expression. + // We want to be able to handle e.g., `concat!("foo", "bar")`. + let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr(); + + ExpandResult::Ready(Err(match expr.kind { + ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) { + Ok(ast::LitKind::Str(s, style)) => { + return ExpandResult::Ready(Ok((s, style, expr.span))); + } + Ok(ast::LitKind::ByteStr(..)) => { + let mut err = cx.dcx().struct_span_err(expr.span, err_msg); + let span = expr.span.shrink_to_lo(); + err.span_suggestion( + span.with_hi(span.lo() + BytePos(1)), + "consider removing the leading `b`", + "", + Applicability::MaybeIncorrect, + ); + Ok((err, true)) + } + Ok(ast::LitKind::Err(guar)) => Err(guar), + Err(err) => Err(report_lit_error(&cx.sess.psess, err, token_lit, expr.span)), + _ => Ok((cx.dcx().struct_span_err(expr.span, err_msg), false)), + }, + ast::ExprKind::Err(guar) => Err(guar), + ast::ExprKind::Dummy => { + cx.dcx().span_bug(expr.span, "tried to get a string literal from `ExprKind::Dummy`") + } + _ => Ok((cx.dcx().struct_span_err(expr.span, err_msg), false)), + })) +} + +/// Extracts a string literal from the macro expanded version of `expr`, +/// emitting `err_msg` if `expr` is not a string literal. This does not stop +/// compilation on error, merely emits a non-fatal error and returns `Err`. +pub(crate) fn expr_to_string( + cx: &mut ExtCtxt<'_>, + expr: P, + err_msg: &'static str, +) -> ExpandResult, ()> { + expr_to_spanned_string(cx, expr, err_msg).map(|res| { + res.map_err(|err| match err { + Ok((err, _)) => err.emit(), + Err(guar) => guar, + }) + .map(|(symbol, style, _)| (symbol, style)) + }) +} + +/// Non-fatally assert that `tts` is empty. Note that this function +/// returns even when `tts` is non-empty, macros that *need* to stop +/// compilation should call `cx.diagnostic().abort_if_errors()` +/// (this should be done as rarely as possible). +pub(crate) fn check_zero_tts(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream, name: &str) { + if !tts.is_empty() { + cx.dcx().emit_err(errors::TakesNoArguments { span, name }); + } +} + +/// Parse an expression. On error, emit it, advancing to `Eof`, and return `Err`. +pub(crate) fn parse_expr(p: &mut parser::Parser<'_>) -> Result, ErrorGuaranteed> { + let guar = match p.parse_expr() { + Ok(expr) => return Ok(expr), + Err(err) => err.emit(), + }; + while p.token != token::Eof { + p.bump(); + } + Err(guar) +} + +/// Interpreting `tts` as a comma-separated sequence of expressions, +/// expect exactly one string literal, or emit an error and return `Err`. +pub(crate) fn get_single_str_from_tts( + cx: &mut ExtCtxt<'_>, + span: Span, + tts: TokenStream, + name: &str, +) -> ExpandResult, ()> { + get_single_str_spanned_from_tts(cx, span, tts, name).map(|res| res.map(|(s, _)| s)) +} + +pub(crate) fn get_single_str_spanned_from_tts( + cx: &mut ExtCtxt<'_>, + span: Span, + tts: TokenStream, + name: &str, +) -> ExpandResult, ()> { + let mut p = cx.new_parser_from_tts(tts); + if p.token == token::Eof { + let guar = cx.dcx().emit_err(errors::OnlyOneArgument { span, name }); + return ExpandResult::Ready(Err(guar)); + } + let ret = match parse_expr(&mut p) { + Ok(ret) => ret, + Err(guar) => return ExpandResult::Ready(Err(guar)), + }; + let _ = p.eat(&token::Comma); + + if p.token != token::Eof { + cx.dcx().emit_err(errors::OnlyOneArgument { span, name }); + } + expr_to_spanned_string(cx, ret, "argument must be a string literal").map(|res| { + res.map_err(|err| match err { + Ok((err, _)) => err.emit(), + Err(guar) => guar, + }) + .map(|(symbol, _style, span)| (symbol, span)) + }) +} + +/// Extracts comma-separated expressions from `tts`. +/// On error, emit it, and return `Err`. +pub(crate) fn get_exprs_from_tts( + cx: &mut ExtCtxt<'_>, + tts: TokenStream, +) -> ExpandResult>, ErrorGuaranteed>, ()> { + let mut p = cx.new_parser_from_tts(tts); + let mut es = Vec::new(); + while p.token != token::Eof { + let expr = match parse_expr(&mut p) { + Ok(expr) => expr, + Err(guar) => return ExpandResult::Ready(Err(guar)), + }; + if !cx.force_mode + && let ast::ExprKind::MacCall(m) = &expr.kind + && cx.resolver.macro_accessible(cx.current_expansion.id, &m.path).is_err() + { + return ExpandResult::Retry(()); + } + + // Perform eager expansion on the expression. + // We want to be able to handle e.g., `concat!("foo", "bar")`. + let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr(); + + es.push(expr); + if p.eat(&token::Comma) { + continue; + } + if p.token != token::Eof { + let guar = cx.dcx().emit_err(errors::ExpectedCommaInList { span: p.token.span }); + return ExpandResult::Ready(Err(guar)); + } + } + ExpandResult::Ready(Ok(es)) +} diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl index fdd1a87cae80..b7aae2af9ef9 100644 --- a/compiler/rustc_expand/messages.ftl +++ b/compiler/rustc_expand/messages.ftl @@ -30,9 +30,6 @@ expand_duplicate_matcher_binding = duplicate matcher binding .label = duplicate binding .label2 = previous binding -expand_expected_comma_in_list = - expected token: `,` - expand_expected_paren_or_brace = expected `(` or `{"{"}`, found `{$token}` @@ -116,9 +113,6 @@ expand_must_repeat_once = expand_not_a_meta_item = not a meta item -expand_only_one_argument = - {$name} takes 1 argument - expand_only_one_word = must only be one word @@ -146,9 +140,6 @@ expand_remove_node_not_supported = expand_resolve_relative_path = cannot resolve relative path in non-file source `{$path}` -expand_takes_no_arguments = - {$name} takes no arguments - expand_trace_macro = trace_macro expand_unsupported_key_value = diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index d75c2530710a..10067ba29746 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -5,27 +5,26 @@ use crate::module::DirOwnership; use rustc_ast::attr::MarkedAttrs; use rustc_ast::ptr::P; -use rustc_ast::token::{self, Nonterminal}; +use rustc_ast::token::Nonterminal; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{AssocCtxt, Visitor}; use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind}; use rustc_attr::{self as attr, Deprecation, Stability}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::{self, Lrc}; -use rustc_errors::{Applicability, Diag, DiagCtxt, ErrorGuaranteed, PResult}; +use rustc_errors::{DiagCtxt, ErrorGuaranteed, PResult}; use rustc_feature::Features; use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT; use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiag, RegisteredTools}; use rustc_parse::{parser, MACRO_ARGUMENTS}; use rustc_session::config::CollapseMacroDebuginfo; -use rustc_session::errors::report_lit_error; use rustc_session::{parse::ParseSess, Limit, Session}; use rustc_span::def_id::{CrateNum, DefId, LocalDefId}; use rustc_span::edition::Edition; use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId}; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::{BytePos, FileName, Span, DUMMY_SP}; +use rustc_span::{FileName, Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; use std::default::Default; use std::iter; @@ -1274,181 +1273,6 @@ pub fn resolve_path(sess: &Session, path: impl Into, span: Span) -> PRe } } -/// `Ok` represents successfully retrieving the string literal at the correct -/// position, e.g., `println("abc")`. -type ExprToSpannedStringResult<'a> = Result<(Symbol, ast::StrStyle, Span), UnexpectedExprKind<'a>>; - -/// - `Ok` is returned when the conversion to a string literal is unsuccessful, -/// but another type of expression is obtained instead. -/// - `Err` is returned when the conversion process fails. -type UnexpectedExprKind<'a> = Result<(Diag<'a>, bool /* has_suggestions */), ErrorGuaranteed>; - -/// Extracts a string literal from the macro expanded version of `expr`, -/// returning a diagnostic error of `err_msg` if `expr` is not a string literal. -/// The returned bool indicates whether an applicable suggestion has already been -/// added to the diagnostic to avoid emitting multiple suggestions. `Err(Err(ErrorGuaranteed))` -/// indicates that an ast error was encountered. -// FIXME(Nilstrieb) Make this function setup translatable -#[allow(rustc::untranslatable_diagnostic)] -pub fn expr_to_spanned_string<'a>( - cx: &'a mut ExtCtxt<'_>, - expr: P, - err_msg: &'static str, -) -> ExpandResult, ()> { - if !cx.force_mode - && let ast::ExprKind::MacCall(m) = &expr.kind - && cx.resolver.macro_accessible(cx.current_expansion.id, &m.path).is_err() - { - return ExpandResult::Retry(()); - } - - // Perform eager expansion on the expression. - // We want to be able to handle e.g., `concat!("foo", "bar")`. - let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr(); - - ExpandResult::Ready(Err(match expr.kind { - ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) { - Ok(ast::LitKind::Str(s, style)) => { - return ExpandResult::Ready(Ok((s, style, expr.span))); - } - Ok(ast::LitKind::ByteStr(..)) => { - let mut err = cx.dcx().struct_span_err(expr.span, err_msg); - let span = expr.span.shrink_to_lo(); - err.span_suggestion( - span.with_hi(span.lo() + BytePos(1)), - "consider removing the leading `b`", - "", - Applicability::MaybeIncorrect, - ); - Ok((err, true)) - } - Ok(ast::LitKind::Err(guar)) => Err(guar), - Err(err) => Err(report_lit_error(&cx.sess.psess, err, token_lit, expr.span)), - _ => Ok((cx.dcx().struct_span_err(expr.span, err_msg), false)), - }, - ast::ExprKind::Err(guar) => Err(guar), - ast::ExprKind::Dummy => { - cx.dcx().span_bug(expr.span, "tried to get a string literal from `ExprKind::Dummy`") - } - _ => Ok((cx.dcx().struct_span_err(expr.span, err_msg), false)), - })) -} - -/// Extracts a string literal from the macro expanded version of `expr`, -/// emitting `err_msg` if `expr` is not a string literal. This does not stop -/// compilation on error, merely emits a non-fatal error and returns `Err`. -pub fn expr_to_string( - cx: &mut ExtCtxt<'_>, - expr: P, - err_msg: &'static str, -) -> ExpandResult, ()> { - expr_to_spanned_string(cx, expr, err_msg).map(|res| { - res.map_err(|err| match err { - Ok((err, _)) => err.emit(), - Err(guar) => guar, - }) - .map(|(symbol, style, _)| (symbol, style)) - }) -} - -/// Non-fatally assert that `tts` is empty. Note that this function -/// returns even when `tts` is non-empty, macros that *need* to stop -/// compilation should call `cx.diagnostic().abort_if_errors()` -/// (this should be done as rarely as possible). -pub fn check_zero_tts(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream, name: &str) { - if !tts.is_empty() { - cx.dcx().emit_err(errors::TakesNoArguments { span, name }); - } -} - -/// Parse an expression. On error, emit it, advancing to `Eof`, and return `Err`. -pub fn parse_expr(p: &mut parser::Parser<'_>) -> Result, ErrorGuaranteed> { - let guar = match p.parse_expr() { - Ok(expr) => return Ok(expr), - Err(err) => err.emit(), - }; - while p.token != token::Eof { - p.bump(); - } - Err(guar) -} - -/// Interpreting `tts` as a comma-separated sequence of expressions, -/// expect exactly one string literal, or emit an error and return `Err`. -pub fn get_single_str_from_tts( - cx: &mut ExtCtxt<'_>, - span: Span, - tts: TokenStream, - name: &str, -) -> ExpandResult, ()> { - get_single_str_spanned_from_tts(cx, span, tts, name).map(|res| res.map(|(s, _)| s)) -} - -pub fn get_single_str_spanned_from_tts( - cx: &mut ExtCtxt<'_>, - span: Span, - tts: TokenStream, - name: &str, -) -> ExpandResult, ()> { - let mut p = cx.new_parser_from_tts(tts); - if p.token == token::Eof { - let guar = cx.dcx().emit_err(errors::OnlyOneArgument { span, name }); - return ExpandResult::Ready(Err(guar)); - } - let ret = match parse_expr(&mut p) { - Ok(ret) => ret, - Err(guar) => return ExpandResult::Ready(Err(guar)), - }; - let _ = p.eat(&token::Comma); - - if p.token != token::Eof { - cx.dcx().emit_err(errors::OnlyOneArgument { span, name }); - } - expr_to_spanned_string(cx, ret, "argument must be a string literal").map(|res| { - res.map_err(|err| match err { - Ok((err, _)) => err.emit(), - Err(guar) => guar, - }) - .map(|(symbol, _style, span)| (symbol, span)) - }) -} - -/// Extracts comma-separated expressions from `tts`. -/// On error, emit it, and return `Err`. -pub fn get_exprs_from_tts( - cx: &mut ExtCtxt<'_>, - tts: TokenStream, -) -> ExpandResult>, ErrorGuaranteed>, ()> { - let mut p = cx.new_parser_from_tts(tts); - let mut es = Vec::new(); - while p.token != token::Eof { - let expr = match parse_expr(&mut p) { - Ok(expr) => expr, - Err(guar) => return ExpandResult::Ready(Err(guar)), - }; - if !cx.force_mode - && let ast::ExprKind::MacCall(m) = &expr.kind - && cx.resolver.macro_accessible(cx.current_expansion.id, &m.path).is_err() - { - return ExpandResult::Retry(()); - } - - // Perform eager expansion on the expression. - // We want to be able to handle e.g., `concat!("foo", "bar")`. - let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr(); - - es.push(expr); - if p.eat(&token::Comma) { - continue; - } - if p.token != token::Eof { - let guar = cx.dcx().emit_err(errors::ExpectedCommaInList { span: p.token.span }); - return ExpandResult::Ready(Err(guar)); - } - } - ExpandResult::Ready(Ok(es)) -} - pub fn parse_macro_name_and_helper_attrs( dcx: &rustc_errors::DiagCtxt, attr: &Attribute, diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index 21ce5e1d81e6..db8e4ba07e80 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -152,29 +152,6 @@ pub(crate) struct HelperAttributeNameInvalid { pub name: Ident, } -#[derive(Diagnostic)] -#[diag(expand_expected_comma_in_list)] -pub(crate) struct ExpectedCommaInList { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(expand_only_one_argument)] -pub(crate) struct OnlyOneArgument<'a> { - #[primary_span] - pub span: Span, - pub name: &'a str, -} - -#[derive(Diagnostic)] -#[diag(expand_takes_no_arguments)] -pub(crate) struct TakesNoArguments<'a> { - #[primary_span] - pub span: Span, - pub name: &'a str, -} - #[derive(Diagnostic)] #[diag(expand_feature_removed, code = E0557)] pub(crate) struct FeatureRemoved<'a> { From 30d6f63b4eb24b830c4cee5512401b0f4e61d289 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 26 Apr 2024 07:56:48 +1000 Subject: [PATCH 066/279] Adjust some `pub`s. --- .../src/alloc_error_handler.rs | 2 +- compiler/rustc_builtin_macros/src/assert.rs | 2 +- compiler/rustc_builtin_macros/src/cfg.rs | 2 +- .../rustc_builtin_macros/src/compile_error.rs | 2 +- compiler/rustc_builtin_macros/src/concat.rs | 2 +- .../rustc_builtin_macros/src/concat_bytes.rs | 2 +- .../rustc_builtin_macros/src/concat_idents.rs | 2 +- .../src/deriving/bounds.rs | 4 +-- .../src/deriving/clone.rs | 2 +- .../src/deriving/cmp/eq.rs | 2 +- .../src/deriving/cmp/ord.rs | 4 +-- .../src/deriving/cmp/partial_eq.rs | 2 +- .../src/deriving/cmp/partial_ord.rs | 2 +- .../src/deriving/debug.rs | 2 +- .../src/deriving/decodable.rs | 2 +- .../src/deriving/default.rs | 2 +- .../src/deriving/encodable.rs | 2 +- .../src/deriving/generic/mod.rs | 32 +++++++++---------- .../src/deriving/generic/ty.rs | 14 ++++---- .../rustc_builtin_macros/src/deriving/hash.rs | 2 +- .../rustc_builtin_macros/src/deriving/mod.rs | 24 +++++++------- .../rustc_builtin_macros/src/edition_panic.rs | 6 ++-- compiler/rustc_builtin_macros/src/env.rs | 4 +-- compiler/rustc_builtin_macros/src/errors.rs | 2 +- compiler/rustc_builtin_macros/src/format.rs | 4 +-- .../src/global_allocator.rs | 2 +- .../rustc_builtin_macros/src/log_syntax.rs | 2 +- .../rustc_builtin_macros/src/pattern_type.rs | 2 +- .../rustc_builtin_macros/src/source_util.rs | 16 +++++----- compiler/rustc_builtin_macros/src/test.rs | 8 ++--- .../rustc_builtin_macros/src/trace_macros.rs | 2 +- compiler/rustc_builtin_macros/src/util.rs | 4 +-- 32 files changed, 81 insertions(+), 81 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index bc94e0b972b4..064cf7d7f0f8 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -9,7 +9,7 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; use thin_vec::{thin_vec, ThinVec}; -pub fn expand( +pub(crate) fn expand( ecx: &mut ExtCtxt<'_>, _span: Span, meta_item: &ast::MetaItem, diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index d200179f3a0a..c75050f27018 100644 --- a/compiler/rustc_builtin_macros/src/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs @@ -15,7 +15,7 @@ use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use thin_vec::thin_vec; -pub fn expand_assert<'cx>( +pub(crate) fn expand_assert<'cx>( cx: &'cx mut ExtCtxt<'_>, span: Span, tts: TokenStream, diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index 5dc9bbacd062..827719d79449 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -11,7 +11,7 @@ use rustc_errors::PResult; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult}; use rustc_span::Span; -pub fn expand_cfg( +pub(crate) fn expand_cfg( cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream, diff --git a/compiler/rustc_builtin_macros/src/compile_error.rs b/compiler/rustc_builtin_macros/src/compile_error.rs index 833e9cb5d75a..a08e8b2819b5 100644 --- a/compiler/rustc_builtin_macros/src/compile_error.rs +++ b/compiler/rustc_builtin_macros/src/compile_error.rs @@ -5,7 +5,7 @@ use rustc_ast::tokenstream::TokenStream; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult}; use rustc_span::Span; -pub fn expand_compile_error<'cx>( +pub(crate) fn expand_compile_error<'cx>( cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream, diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs index 125f4bc6dc4a..15af79ef67d4 100644 --- a/compiler/rustc_builtin_macros/src/concat.rs +++ b/compiler/rustc_builtin_macros/src/concat.rs @@ -6,7 +6,7 @@ use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpa use rustc_session::errors::report_lit_error; use rustc_span::symbol::Symbol; -pub fn expand_concat( +pub(crate) fn expand_concat( cx: &mut ExtCtxt<'_>, sp: rustc_span::Span, tts: TokenStream, diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs index f9d3f4a14258..3130870df410 100644 --- a/compiler/rustc_builtin_macros/src/concat_bytes.rs +++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs @@ -107,7 +107,7 @@ fn handle_array_element( None } -pub fn expand_concat_bytes( +pub(crate) fn expand_concat_bytes( cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream, diff --git a/compiler/rustc_builtin_macros/src/concat_idents.rs b/compiler/rustc_builtin_macros/src/concat_idents.rs index 3ddb0ae45b51..13729a9d250f 100644 --- a/compiler/rustc_builtin_macros/src/concat_idents.rs +++ b/compiler/rustc_builtin_macros/src/concat_idents.rs @@ -8,7 +8,7 @@ use rustc_span::Span; use crate::errors; -pub fn expand_concat_idents<'cx>( +pub(crate) fn expand_concat_idents<'cx>( cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream, diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs index 26ef3da3a915..97e2344ff30e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs +++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs @@ -5,7 +5,7 @@ use rustc_ast::MetaItem; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::Span; -pub fn expand_deriving_copy( +pub(crate) fn expand_deriving_copy( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, @@ -28,7 +28,7 @@ pub fn expand_deriving_copy( trait_def.expand(cx, mitem, item, push); } -pub fn expand_deriving_const_param_ty( +pub(crate) fn expand_deriving_const_param_ty( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index cb1c9ef90bde..abcb402a46f8 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -8,7 +8,7 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; use thin_vec::{thin_vec, ThinVec}; -pub fn expand_deriving_clone( +pub(crate) fn expand_deriving_clone( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs index 45c4467a1097..53a151316054 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs @@ -9,7 +9,7 @@ use rustc_span::symbol::sym; use rustc_span::Span; use thin_vec::{thin_vec, ThinVec}; -pub fn expand_deriving_eq( +pub(crate) fn expand_deriving_eq( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs index 1d7a69540ab8..8470d466a233 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs @@ -7,7 +7,7 @@ use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use thin_vec::thin_vec; -pub fn expand_deriving_ord( +pub(crate) fn expand_deriving_ord( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, @@ -39,7 +39,7 @@ pub fn expand_deriving_ord( trait_def.expand(cx, mitem, item, push) } -pub fn cs_cmp(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr { +pub(crate) fn cs_cmp(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr { let test_id = Ident::new(sym::cmp, span); let equal_path = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal])); let cmp_path = cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]); diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs index 234918ae4296..dc73caa4ad5b 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs @@ -8,7 +8,7 @@ use rustc_span::symbol::sym; use rustc_span::Span; use thin_vec::thin_vec; -pub fn expand_deriving_partial_eq( +pub(crate) fn expand_deriving_partial_eq( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs index 63311c897aba..006e5a3d268a 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs @@ -7,7 +7,7 @@ use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use thin_vec::thin_vec; -pub fn expand_deriving_partial_ord( +pub(crate) fn expand_deriving_partial_ord( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 8b681db96705..57ec0435e3e0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -8,7 +8,7 @@ use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; use thin_vec::{thin_vec, ThinVec}; -pub fn expand_deriving_debug( +pub(crate) fn expand_deriving_debug( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs index 34798ab0a17b..e9851c87aeae 100644 --- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs @@ -10,7 +10,7 @@ use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; use thin_vec::{thin_vec, ThinVec}; -pub fn expand_deriving_rustc_decodable( +pub(crate) fn expand_deriving_rustc_decodable( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 328770ce10d2..bf92ddb33701 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -12,7 +12,7 @@ use rustc_span::{ErrorGuaranteed, Span}; use smallvec::SmallVec; use thin_vec::{thin_vec, ThinVec}; -pub fn expand_deriving_default( +pub(crate) fn expand_deriving_default( cx: &ExtCtxt<'_>, span: Span, mitem: &ast::MetaItem, diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs index 2e5f1173825a..3bd74d8d0198 100644 --- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs @@ -94,7 +94,7 @@ use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; use thin_vec::{thin_vec, ThinVec}; -pub fn expand_deriving_rustc_encodable( +pub(crate) fn expand_deriving_rustc_encodable( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 85d54e9257d8..52c1ba1757b1 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -174,8 +174,8 @@ //! ) //! ``` -pub use StaticFields::*; -pub use SubstructureFields::*; +pub(crate) use StaticFields::*; +pub(crate) use SubstructureFields::*; use crate::{deriving, errors}; use rustc_ast::ptr::P; @@ -195,9 +195,9 @@ use std::vec; use thin_vec::{thin_vec, ThinVec}; use ty::{Bounds, Path, Ref, Self_, Ty}; -pub mod ty; +pub(crate) mod ty; -pub struct TraitDef<'a> { +pub(crate) struct TraitDef<'a> { /// The span for the current #[derive(Foo)] header. pub span: Span, @@ -224,7 +224,7 @@ pub struct TraitDef<'a> { pub is_const: bool, } -pub struct MethodDef<'a> { +pub(crate) struct MethodDef<'a> { /// name of the method pub name: Symbol, /// List of generics, e.g., `R: rand::Rng` @@ -248,7 +248,7 @@ pub struct MethodDef<'a> { /// How to handle fieldless enum variants. #[derive(PartialEq)] -pub enum FieldlessVariantsStrategy { +pub(crate) enum FieldlessVariantsStrategy { /// Combine fieldless variants into a single match arm. /// This assumes that relevant information has been handled /// by looking at the enum's discriminant. @@ -263,7 +263,7 @@ pub enum FieldlessVariantsStrategy { } /// All the data about the data structure/method being derived upon. -pub struct Substructure<'a> { +pub(crate) struct Substructure<'a> { /// ident of self pub type_ident: Ident, /// Verbatim access to any non-selflike arguments, i.e. arguments that @@ -273,7 +273,7 @@ pub struct Substructure<'a> { } /// Summary of the relevant parts of a struct/enum field. -pub struct FieldInfo { +pub(crate) struct FieldInfo { pub span: Span, /// None for tuple structs/normal enum variants, Some for normal /// structs/struct enum variants. @@ -287,13 +287,13 @@ pub struct FieldInfo { } #[derive(Copy, Clone)] -pub enum IsTuple { +pub(crate) enum IsTuple { No, Yes, } /// Fields for a static method -pub enum StaticFields { +pub(crate) enum StaticFields { /// Tuple and unit structs/enum variants like this. Unnamed(Vec, IsTuple), /// Normal structs/struct variants. @@ -301,7 +301,7 @@ pub enum StaticFields { } /// A summary of the possible sets of fields. -pub enum SubstructureFields<'a> { +pub(crate) enum SubstructureFields<'a> { /// A non-static method where `Self` is a struct. Struct(&'a ast::VariantData, Vec), @@ -329,10 +329,10 @@ pub enum SubstructureFields<'a> { /// Combine the values of all the fields together. The last argument is /// all the fields of all the structures. -pub type CombineSubstructureFunc<'a> = +pub(crate) type CombineSubstructureFunc<'a> = Box, Span, &Substructure<'_>) -> BlockOrExpr + 'a>; -pub fn combine_substructure( +pub(crate) fn combine_substructure( f: CombineSubstructureFunc<'_>, ) -> RefCell> { RefCell::new(f) @@ -349,7 +349,7 @@ struct TypeParameter { /// avoiding the insertion of any unnecessary blocks. /// /// The statements come before the expression. -pub struct BlockOrExpr(ThinVec, Option>); +pub(crate) struct BlockOrExpr(ThinVec, Option>); impl BlockOrExpr { pub fn new_stmts(stmts: ThinVec) -> BlockOrExpr { @@ -1647,7 +1647,7 @@ impl<'a> TraitDef<'a> { /// The function passed to `cs_fold` is called repeatedly with a value of this /// type. It describes one part of the code generation. The result is always an /// expression. -pub enum CsFold<'a> { +pub(crate) enum CsFold<'a> { /// The basic case: a field expression for one or more selflike args. E.g. /// for `PartialEq::eq` this is something like `self.x == other.x`. Single(&'a FieldInfo), @@ -1662,7 +1662,7 @@ pub enum CsFold<'a> { /// Folds over fields, combining the expressions for each field in a sequence. /// Statics may not be folded over. -pub fn cs_fold( +pub(crate) fn cs_fold( use_foldl: bool, cx: &ExtCtxt<'_>, trait_span: Span, diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs index 188833246832..f01d586033e0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs @@ -1,7 +1,7 @@ //! A mini version of ast::Ty, which is easier to use, and features an explicit `Self` type to use //! when specifying impls to be derived. -pub use Ty::*; +pub(crate) use Ty::*; use rustc_ast::ptr::P; use rustc_ast::{self as ast, Expr, GenericArg, GenericParamKind, Generics, SelfKind}; @@ -14,14 +14,14 @@ use thin_vec::ThinVec; /// A path, e.g., `::std::option::Option::` (global). Has support /// for type parameters. #[derive(Clone)] -pub struct Path { +pub(crate) struct Path { path: Vec, params: Vec>, kind: PathKind, } #[derive(Clone)] -pub enum PathKind { +pub(crate) enum PathKind { Local, Global, Std, @@ -72,7 +72,7 @@ impl Path { /// A type. Supports pointers, Self, and literals. #[derive(Clone)] -pub enum Ty { +pub(crate) enum Ty { Self_, /// A reference. Ref(Box, ast::Mutability), @@ -83,7 +83,7 @@ pub enum Ty { Unit, } -pub fn self_ref() -> Ty { +pub(crate) fn self_ref() -> Ty { Ref(Box::new(Self_), ast::Mutability::Not) } @@ -163,7 +163,7 @@ fn mk_ty_param( /// Bounds on type parameters. #[derive(Clone)] -pub struct Bounds { +pub(crate) struct Bounds { pub bounds: Vec<(Symbol, Vec)>, } @@ -196,7 +196,7 @@ impl Bounds { } } -pub fn get_explicit_self(cx: &ExtCtxt<'_>, span: Span) -> (P, ast::ExplicitSelf) { +pub(crate) fn get_explicit_self(cx: &ExtCtxt<'_>, span: Span) -> (P, ast::ExplicitSelf) { // This constructs a fresh `self` path. let self_path = cx.expr_self(span); let self_ty = respan(span, SelfKind::Region(None, ast::Mutability::Not)); diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 41e27f655866..dcd928198651 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -7,7 +7,7 @@ use rustc_span::symbol::sym; use rustc_span::Span; use thin_vec::thin_vec; -pub fn expand_deriving_hash( +pub(crate) fn expand_deriving_hash( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index 9f786d22c932..d6e2d1d4d07f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -20,24 +20,24 @@ macro path_std($($x:tt)*) { generic::ty::Path::new( pathvec_std!( $($x)* ) ) } -pub mod bounds; -pub mod clone; -pub mod debug; -pub mod decodable; -pub mod default; -pub mod encodable; -pub mod hash; +pub(crate) mod bounds; +pub(crate) mod clone; +pub(crate) mod debug; +pub(crate) mod decodable; +pub(crate) mod default; +pub(crate) mod encodable; +pub(crate) mod hash; #[path = "cmp/eq.rs"] -pub mod eq; +pub(crate) mod eq; #[path = "cmp/ord.rs"] -pub mod ord; +pub(crate) mod ord; #[path = "cmp/partial_eq.rs"] -pub mod partial_eq; +pub(crate) mod partial_eq; #[path = "cmp/partial_ord.rs"] -pub mod partial_ord; +pub(crate) mod partial_ord; -pub mod generic; +pub(crate) mod generic; pub(crate) type BuiltinDeriveFn = fn(&ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable), bool); diff --git a/compiler/rustc_builtin_macros/src/edition_panic.rs b/compiler/rustc_builtin_macros/src/edition_panic.rs index bb3c83e8c0e3..cc385bade470 100644 --- a/compiler/rustc_builtin_macros/src/edition_panic.rs +++ b/compiler/rustc_builtin_macros/src/edition_panic.rs @@ -16,7 +16,7 @@ use rustc_span::Span; /// /// `$crate` will refer to either the `std` or `core` crate depending on which /// one we're expanding from. -pub fn expand_panic<'cx>( +pub(crate) fn expand_panic<'cx>( cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream, @@ -29,7 +29,7 @@ pub fn expand_panic<'cx>( /// - `$crate::panic::unreachable_2015!(...)` or /// - `$crate::panic::unreachable_2021!(...)` /// depending on the edition. -pub fn expand_unreachable<'cx>( +pub(crate) fn expand_unreachable<'cx>( cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream, @@ -69,7 +69,7 @@ fn expand<'cx>( )) } -pub fn use_panic_2021(mut span: Span) -> bool { +pub(crate) fn use_panic_2021(mut span: Span) -> bool { // To determine the edition, we check the first span up the expansion // stack that does not have #[allow_internal_unstable(edition_panic)]. // (To avoid using the edition of e.g. the assert!() or debug_assert!() definition.) diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index 3903c77b6696..b03e14cf2630 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -25,7 +25,7 @@ fn lookup_env<'cx>(cx: &'cx ExtCtxt<'_>, var: Symbol) -> Result( +pub(crate) fn expand_option_env<'cx>( cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream, @@ -65,7 +65,7 @@ pub fn expand_option_env<'cx>( ExpandResult::Ready(MacEager::expr(e)) } -pub fn expand_env<'cx>( +pub(crate) fn expand_env<'cx>( cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream, diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 055ff79a8ad3..e665d8a3ff2f 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -579,7 +579,7 @@ pub(crate) struct FormatUnknownTrait<'a> { style = "tool-only", applicability = "maybe-incorrect" )] -pub struct FormatUnknownTraitSugg { +pub(crate) struct FormatUnknownTraitSugg { #[primary_span] pub span: Span, pub fmt: &'static str, diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 3f44096714c0..2c717661a1c4 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -1000,7 +1000,7 @@ fn expand_format_args_impl<'cx>( }) } -pub fn expand_format_args<'cx>( +pub(crate) fn expand_format_args<'cx>( ecx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream, @@ -1008,7 +1008,7 @@ pub fn expand_format_args<'cx>( expand_format_args_impl(ecx, sp, tts, false) } -pub fn expand_format_args_nl<'cx>( +pub(crate) fn expand_format_args_nl<'cx>( ecx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream, diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index 099defd511b5..a1630ad1379e 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -12,7 +12,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; use thin_vec::{thin_vec, ThinVec}; -pub fn expand( +pub(crate) fn expand( ecx: &mut ExtCtxt<'_>, _span: Span, meta_item: &ast::MetaItem, diff --git a/compiler/rustc_builtin_macros/src/log_syntax.rs b/compiler/rustc_builtin_macros/src/log_syntax.rs index 288a475ac241..205f21ae7c9d 100644 --- a/compiler/rustc_builtin_macros/src/log_syntax.rs +++ b/compiler/rustc_builtin_macros/src/log_syntax.rs @@ -2,7 +2,7 @@ use rustc_ast::tokenstream::TokenStream; use rustc_ast_pretty::pprust; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult}; -pub fn expand_log_syntax<'cx>( +pub(crate) fn expand_log_syntax<'cx>( _cx: &'cx mut ExtCtxt<'_>, sp: rustc_span::Span, tts: TokenStream, diff --git a/compiler/rustc_builtin_macros/src/pattern_type.rs b/compiler/rustc_builtin_macros/src/pattern_type.rs index 54039c2c5386..31f5656df135 100644 --- a/compiler/rustc_builtin_macros/src/pattern_type.rs +++ b/compiler/rustc_builtin_macros/src/pattern_type.rs @@ -3,7 +3,7 @@ use rustc_errors::PResult; use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult}; use rustc_span::{sym, Span}; -pub fn expand<'cx>( +pub(crate) fn expand<'cx>( cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream, diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index 033c7446b266..47b2ee975ca8 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -26,7 +26,7 @@ use std::rc::Rc; // a given file into the current one. /// line!(): expands to the current line number -pub fn expand_line( +pub(crate) fn expand_line( cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream, @@ -41,7 +41,7 @@ pub fn expand_line( } /* column!(): expands to the current column number */ -pub fn expand_column( +pub(crate) fn expand_column( cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream, @@ -58,7 +58,7 @@ pub fn expand_column( /// file!(): expands to the current filename */ /// The source_file (`loc.file`) contains a bunch more information we could spit /// out if we wanted. -pub fn expand_file( +pub(crate) fn expand_file( cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream, @@ -78,7 +78,7 @@ pub fn expand_file( ))) } -pub fn expand_stringify( +pub(crate) fn expand_stringify( cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream, @@ -88,7 +88,7 @@ pub fn expand_stringify( ExpandResult::Ready(MacEager::expr(cx.expr_str(sp, Symbol::intern(&s)))) } -pub fn expand_mod( +pub(crate) fn expand_mod( cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream, @@ -104,7 +104,7 @@ pub fn expand_mod( /// include! : parse the given file as an expr /// This is generally a bad idea because it's going to behave /// unhygienically. -pub fn expand_include<'cx>( +pub(crate) fn expand_include<'cx>( cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream, @@ -181,7 +181,7 @@ pub fn expand_include<'cx>( } /// `include_str!`: read the given file, insert it as a literal string expr -pub fn expand_include_str( +pub(crate) fn expand_include_str( cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream, @@ -210,7 +210,7 @@ pub fn expand_include_str( }) } -pub fn expand_include_bytes( +pub(crate) fn expand_include_bytes( cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream, diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index c7568f1461c1..134d5451b9c1 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -20,7 +20,7 @@ use thin_vec::{thin_vec, ThinVec}; /// /// We mark item with an inert attribute "rustc_test_marker" which the test generation /// logic will pick up on. -pub fn expand_test_case( +pub(crate) fn expand_test_case( ecx: &mut ExtCtxt<'_>, attr_sp: Span, meta_item: &ast::MetaItem, @@ -73,7 +73,7 @@ pub fn expand_test_case( vec![ret] } -pub fn expand_test( +pub(crate) fn expand_test( cx: &mut ExtCtxt<'_>, attr_sp: Span, meta_item: &ast::MetaItem, @@ -84,7 +84,7 @@ pub fn expand_test( expand_test_or_bench(cx, attr_sp, item, false) } -pub fn expand_bench( +pub(crate) fn expand_bench( cx: &mut ExtCtxt<'_>, attr_sp: Span, meta_item: &ast::MetaItem, @@ -95,7 +95,7 @@ pub fn expand_bench( expand_test_or_bench(cx, attr_sp, item, true) } -pub fn expand_test_or_bench( +pub(crate) fn expand_test_or_bench( cx: &ExtCtxt<'_>, attr_sp: Span, item: Annotatable, diff --git a/compiler/rustc_builtin_macros/src/trace_macros.rs b/compiler/rustc_builtin_macros/src/trace_macros.rs index 696d99004ba0..4833ec32f76e 100644 --- a/compiler/rustc_builtin_macros/src/trace_macros.rs +++ b/compiler/rustc_builtin_macros/src/trace_macros.rs @@ -4,7 +4,7 @@ use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult use rustc_span::symbol::kw; use rustc_span::Span; -pub fn expand_trace_macros( +pub(crate) fn expand_trace_macros( cx: &mut ExtCtxt<'_>, sp: Span, tt: TokenStream, diff --git a/compiler/rustc_builtin_macros/src/util.rs b/compiler/rustc_builtin_macros/src/util.rs index 49687c6a0ade..8dc7bc14ec3e 100644 --- a/compiler/rustc_builtin_macros/src/util.rs +++ b/compiler/rustc_builtin_macros/src/util.rs @@ -10,7 +10,7 @@ use rustc_parse::{parser, validate_attr}; use rustc_session::errors::report_lit_error; use rustc_span::{BytePos, Span, Symbol}; -pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, name: Symbol) { +pub(crate) fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, name: Symbol) { // All the built-in macro attributes are "words" at the moment. let template = AttributeTemplate { word: true, ..Default::default() }; validate_attr::check_builtin_meta_item( @@ -24,7 +24,7 @@ pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, na /// Emit a warning if the item is annotated with the given attribute. This is used to diagnose when /// an attribute may have been mistakenly duplicated. -pub fn warn_on_duplicate_attribute(ecx: &ExtCtxt<'_>, item: &Annotatable, name: Symbol) { +pub(crate) fn warn_on_duplicate_attribute(ecx: &ExtCtxt<'_>, item: &Annotatable, name: Symbol) { let attrs: Option<&[Attribute]> = match item { Annotatable::Item(item) => Some(&item.attrs), Annotatable::TraitItem(item) => Some(&item.attrs), From cd47a0ed086ca89faa64776ff15e118ba6aa27f3 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 25 Apr 2024 22:16:02 -0700 Subject: [PATCH 067/279] Convert some iter macros to normal functions With all the MIR optimization changes that have happened since these were written, let's see if they still actually matter. --- library/core/src/slice/iter/macros.rs | 41 +++++++++++++-------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index 7910981d0f5e..0b8ff5cc0124 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -70,21 +70,19 @@ macro_rules! iterator { $into_ref:ident, {$($extra:tt)*} ) => { - // Returns the first element and moves the start of the iterator forwards by 1. - // Greatly improves performance compared to an inlined function. The iterator - // must not be empty. - macro_rules! next_unchecked { - ($self: ident) => { $self.post_inc_start(1).$into_ref() } - } - - // Returns the last element and moves the end of the iterator backwards by 1. - // Greatly improves performance compared to an inlined function. The iterator - // must not be empty. - macro_rules! next_back_unchecked { - ($self: ident) => { $self.pre_dec_end(1).$into_ref() } - } - impl<'a, T> $name<'a, T> { + /// Returns the last element and moves the end of the iterator backwards by 1. + /// + /// # Safety + /// + /// The iterator must not be empty + #[inline] + unsafe fn next_back_unchecked(&mut self) -> $elem { + // SAFETY: the caller promised it's not empty, so + // the offsetting is in-bounds and there's an element to return. + unsafe { self.pre_dec_end(1).$into_ref() } + } + // Helper function for creating a slice from the iterator. #[inline(always)] fn make_slice(&self) -> &'a [T] { @@ -156,13 +154,13 @@ macro_rules! iterator { fn next(&mut self) -> Option<$elem> { // could be implemented with slices, but this avoids bounds checks - // SAFETY: The call to `next_unchecked!` is + // SAFETY: The call to `next_unchecked` is // safe since we check if the iterator is empty first. unsafe { if is_empty!(self) { None } else { - Some(next_unchecked!(self)) + Some(self.next_unchecked()) } } } @@ -191,7 +189,7 @@ macro_rules! iterator { // SAFETY: We are in bounds. `post_inc_start` does the right thing even for ZSTs. unsafe { self.post_inc_start(n); - Some(next_unchecked!(self)) + Some(self.next_unchecked()) } } @@ -392,13 +390,13 @@ macro_rules! iterator { fn next_back(&mut self) -> Option<$elem> { // could be implemented with slices, but this avoids bounds checks - // SAFETY: The call to `next_back_unchecked!` + // SAFETY: The call to `next_back_unchecked` // is safe since we check if the iterator is empty first. unsafe { if is_empty!(self) { None } else { - Some(next_back_unchecked!(self)) + Some(self.next_back_unchecked()) } } } @@ -416,7 +414,7 @@ macro_rules! iterator { // SAFETY: We are in bounds. `pre_dec_end` does the right thing even for ZSTs. unsafe { self.pre_dec_end(n); - Some(next_back_unchecked!(self)) + Some(self.next_back_unchecked()) } } @@ -436,10 +434,11 @@ macro_rules! iterator { unsafe impl TrustedLen for $name<'_, T> {} impl<'a, T> UncheckedIterator for $name<'a, T> { + #[inline] unsafe fn next_unchecked(&mut self) -> $elem { // SAFETY: The caller promised there's at least one more item. unsafe { - next_unchecked!(self) + self.post_inc_start(1).$into_ref() } } } From c028782c67e9f2be14fb42aa47ea1645d8eef816 Mon Sep 17 00:00:00 2001 From: Jover Zhang Date: Wed, 24 Apr 2024 21:20:36 +0800 Subject: [PATCH 068/279] Add support for run-make-support unit tests to be run with bootstrap command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Onur Özkan --- src/bootstrap/src/core/build_steps/test.rs | 48 ++++++++++++++++++++++ src/bootstrap/src/core/builder.rs | 1 + 2 files changed, 49 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index ca10a128b981..d581987c29e5 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1371,6 +1371,7 @@ impl Step for RunMakeSupport { run.builder.ensure(RunMakeSupport { compiler, target: run.build_triple() }); } + /// Builds run-make-support and returns the path to the resulting rlib. fn run(self, builder: &Builder<'_>) -> PathBuf { builder.ensure(compile::Std::new(self.compiler, self.target)); @@ -1397,6 +1398,53 @@ impl Step for RunMakeSupport { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct CrateRunMakeSupport { + host: TargetSelection, +} + +impl Step for CrateRunMakeSupport { + type Output = (); + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/run-make-support") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(CrateRunMakeSupport { host: run.target }); + } + + /// Runs `cargo test` for run-make-support. + fn run(self, builder: &Builder<'_>) { + let host = self.host; + let compiler = builder.compiler(builder.top_stage, host); + + builder.ensure(compile::Std::new(compiler, host)); + let mut cargo = tool::prepare_tool_cargo( + builder, + compiler, + Mode::ToolStd, + host, + "test", + "src/tools/run-make-support", + SourceType::InTree, + &[], + ); + cargo.allow_features("test"); + run_cargo_test( + cargo, + &[], + &[], + "run-make-support", + "run-make-support self test", + compiler, + host, + builder, + ); + } +} + default_test!(Ui { path: "tests/ui", mode: "ui", suite: "ui" }); default_test!(Crashes { path: "tests/crashes", mode: "crashes", suite: "crashes" }); diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index adef9ebd0e30..70125aa429d8 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -817,6 +817,7 @@ impl<'a> Builder<'a> { test::Clippy, test::RustDemangler, test::CompiletestTest, + test::CrateRunMakeSupport, test::RustdocJSStd, test::RustdocJSNotStd, test::RustdocGUI, From b0f75628d21ac5409ad0e883f95df0badf13b71d Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Fri, 26 Apr 2024 15:15:35 +0100 Subject: [PATCH 069/279] Add pages for every Cortex-M target Now explains how to, for example, support a Cortex-M55 with FPU and Integer Helium. --- src/doc/rustc/src/platform-support.md | 14 +- .../src/platform-support/arm-none-eabi.md | 141 ++++++++++++++---- .../platform-support/thumbv6m-none-eabi.md | 62 ++++++++ .../platform-support/thumbv7em-none-eabi.md | 70 +++++++++ .../platform-support/thumbv7em-none-eabihf.md | 67 +++++++++ .../platform-support/thumbv7m-none-eabi.md | 44 ++++++ .../thumbv8m.base-none-eabi.md | 44 ++++++ .../thumbv8m.main-none-eabi.md | 124 +++++++++++++++ .../thumbv8m.main-none-eabihf.md | 113 ++++++++++++++ 9 files changed, 643 insertions(+), 36 deletions(-) create mode 100644 src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md create mode 100644 src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md create mode 100644 src/doc/rustc/src/platform-support/thumbv7em-none-eabihf.md create mode 100644 src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md create mode 100644 src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md create mode 100644 src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md create mode 100644 src/doc/rustc/src/platform-support/thumbv8m.main-none-eabihf.md diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 2578b71a158b..526b5a597899 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -178,15 +178,15 @@ target | std | notes `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA) `sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4, glibc 2.23) `sparcv9-sun-solaris` | ✓ | SPARC Solaris 11, illumos -[`thumbv6m-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare ARMv6-M -[`thumbv7em-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare ARMv7E-M -[`thumbv7em-none-eabihf`](platform-support/arm-none-eabi.md) | * | Bare ARMV7E-M, hardfloat -[`thumbv7m-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare ARMv7-M +[`thumbv6m-none-eabi`](platform-support/thumbv6m-none-eabi.md) | * | Bare ARMv6-M +[`thumbv7em-none-eabi`](platform-support/thumbv7em-none-eabi.md) | * | Bare ARMv7E-M +[`thumbv7em-none-eabihf`](platform-support/thumbv7em-none-eabihf.md) | * | Bare ARMV7E-M, hardfloat +[`thumbv7m-none-eabi`](platform-support/thumbv7m-none-eabi.md) | * | Bare ARMv7-M [`thumbv7neon-linux-androideabi`](platform-support/android.md) | ✓ | Thumb2-mode ARMv7-A Android with NEON `thumbv7neon-unknown-linux-gnueabihf` | ✓ | Thumb2-mode ARMv7-A Linux with NEON (kernel 4.4, glibc 2.23) -[`thumbv8m.base-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare ARMv8-M Baseline -[`thumbv8m.main-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare ARMv8-M Mainline -[`thumbv8m.main-none-eabihf`](platform-support/arm-none-eabi.md) | * | Bare ARMv8-M Mainline, hardfloat +[`thumbv8m.base-none-eabi`](platform-support/thumbv8m.base-none-eabi.md) | * | Bare ARMv8-M Baseline +[`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare ARMv8-M Mainline +[`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabihf.md) | * | Bare ARMv8-M Mainline, hardfloat `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten `wasm32-unknown-unknown` | ✓ | WebAssembly `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename]) diff --git a/src/doc/rustc/src/platform-support/arm-none-eabi.md b/src/doc/rustc/src/platform-support/arm-none-eabi.md index 6335a6405a10..de41c5e676a8 100644 --- a/src/doc/rustc/src/platform-support/arm-none-eabi.md +++ b/src/doc/rustc/src/platform-support/arm-none-eabi.md @@ -1,25 +1,96 @@ # `{arm,thumb}*-none-eabi(hf)?` -**Tier: 2** -- [arm(eb)?v7r-none-eabi(hf)?](armv7r-none-eabi.md) -- armv7a-none-eabi -- thumbv6m-none-eabi -- thumbv7m-none-eabi -- thumbv7em-none-eabi(hf)? -- thumbv8m.base-none-eabi -- thumbv8m.main-none-eabi(hf)? +## Tier 2 Target List -**Tier: 3** -- [{arm,thumb}v4t-none-eabi](armv4t-none-eabi.md) -- [{arm,thumb}v5te-none-eabi](armv5te-none-eabi.md) -- armv7a-none-eabihf -- [armv8r-none-eabihf](armv8r-none-eabihf.md) +- Arm A-Profile Architectures + - `armv7a-none-eabi` +- Arm R-Profile Architectures + - [`armv7r-none-eabi` and `armv7r-none-eabihf`](armv7r-none-eabi.md) + - [`armebv7r-none-eabi` and `armebv7r-none-eabihf`](armv7r-none-eabi.md) +- Arm M-Profile Architectures + - [`thumbv6m-none-eabi`](thumbv6m-none-eabi.md) + - [`thumbv7m-none-eabi`](thumbv7m-none-eabi.md) + - [`thumbv7em-none-eabi`](thumbv7em-none-eabi.md) and [`thumbv7em-none-eabihf`](thumbv7em-none-eabihf.md) + - [`thumbv8m.base-none-eabi`](thumbv8m.base-none-eabi.md) + - [`thumbv8m.main-none-eabi`](thumbv8m.main-none-eabi.md) and [`thumbv8m.main-none-eabihf`](thumbv8m.main-none-eabihf.md) +- *Legacy* Arm Architectures + - None -Bare-metal target for 32-bit ARM CPUs. +## Tier 3 Target List -If a target has a `*hf` variant, that variant uses the hardware floating-point -ABI and enables some minimum set of floating-point features based on the FPU(s) -available in that processor family. +- Arm A-Profile Architectures + - `armv7a-none-eabihf` +- Arm R-Profile Architectures + - [`armv8r-none-eabihf`](armv8r-none-eabihf.md) +- Arm M-Profile Architectures + - None +- *Legacy* Arm Architectures + - [`armv4t-none-eabi` and `thumbv4t-none-eabi`](armv4t-none-eabi.md) + - [`armv5te-none-eabi` and `thumbv5te-none-eabi`](armv5te-none-eabi.md) + +## Common Target Details + +This documentation covers details that apply to a range of bare-metal target for +32-bit ARM CPUs. In addition, target specific details may be covered in their +own document. + +If a target ends in `eabi`, that target uses the so-called *soft-float ABI*: +functions which take `f32` or `f64` as arguments will have those values packed +into integer registers. This means that an FPU is not required from an ABI +perspective, but within a function FPU instructions may still be used if the +code is compiled with a `target-cpu` or `target-feature` option that enables +FPU support. + +If a target ends if `eabihf`, that target uses the so-called *hard-float ABI*: +functions which take `f32` or `f64` as arguments will have them passed via FPU +registers. These target therefore require the use of an FPU and will assume the +minimum support FPU for that architecture is available. More advanced FPU +instructions (e.g. ones that work on double-precision `f64` values) may be +generated if the code is compiled with a `target-cpu` or `target-feature` option +that enables such additional FPU support. + +## Target CPU and Target Feature options + +It is possible to tell Rust (or LLVM) that you have a specific model of Arm +processor, using the [`-C target-cpu`][target-cpu] option. You can also control +whether Rust (or LLVM) will include instructions that target optional hardware +features, e.g. hardware floating point, or vector maths operations, using [`-C +target-feature`][target-feature]. + +It is important to note that selecting a *target-cpu* will typically enable +*all* the optional features available from Arm on that model of CPU and your +particular implementation of that CPU may not have those features available. In +that case, you can use `-C target-feature=-option` to turn off the specific CPU +features you do not have available, leaving you with the optimised instruction +scheduling and support for the features you do have. More details are available +in the detailed target-specific documentation. + +**Note:** Many target-features are currently unstable and subject to change, and +if you use them you should dissassmble the compiler output and manually inspect +it to ensure only appropriate instructions for your CPU have been generated. + +If do you wish to use the *target-cpu* and *target-feature* options, you can add +them to your `.cargo/config.toml` file alongside any other flags your project +uses (likely linker related ones): + +```toml +rustflags = [ + # Usual Arm bare-metal linker setup + "-C", "link-arg=-Tlink.x", + "-C", "link-arg=--nmagic", + # tell Rust we have a Cortex-M55 + "-C", "target-cpu=cortex-m55", + # tell Rust our Cortex-M55 doesn't have Floating-Point M-Profile Vector + # Extensions (but it does have everything else a Cortex-M55 could have). + "-C", "target-feature=-mve.fp" +] + +[build] +target = "thumbv8m.main-none-eabihf" +``` + +[target-cpu]: https://doc.rust-lang.org/rustc/codegen-options/index.html#target-cpu +[target-feature]: https://doc.rust-lang.org/rustc/codegen-options/index.html#target-feature ## Requirements @@ -45,14 +116,15 @@ according to the specific device you are using. Pass `-Clink-arg=-Tyour_script.ld` as a rustc argument to make the linker use `your_script.ld` during linking. -Targets named `thumb*` instead of `arm*` -generate Thumb-mode code by default. M-profile processors (`thumbv*m*-*` -targets) only support Thumb-mode code. -For the `arm*` targets, Thumb-mode code generation can be enabled by using -`-C target-feature=+thumb-mode`. Using the unstable -`#![feature(arm_target_feature)]`, the attribute -`#[target_feature(enable = "thumb-mode")]` can be applied to individual -`unsafe` functions to cause those functions to be compiled to Thumb-mode code. +Targets named `thumb*` instead of `arm*` generate Thumb (T32) code by default +instead of Arm (A32) code. Most Arm chips support both Thumb mode and Arm mode, +except that M-profile processors (`thumbv*m*-*` targets) only support Thumb-mode. + +For the `arm*` targets, Thumb-mode code generation can be enabled by using `-C +target-feature=+thumb-mode`. Using the unstable +`#![feature(arm_target_feature)]`, the attribute `#[target_feature(enable = +"thumb-mode")]` can be applied to individual `unsafe` functions to cause those +functions to be compiled to Thumb-mode code. ## Building Rust Programs @@ -69,16 +141,27 @@ build-std = ["core"] ``` Most of `core` should work as expected, with the following notes: -* If the target is not `*hf`, then floating-point operations are emulated in - software. + +* Floating-point operations are emulated in software unless LLVM is told to + enable FPU support (either by using an `eabihf` target, specifying a + `target-cpu` with FPU support, or using a `target-feature` to support for a + specific kind of FPU) * Integer division is also emulated in software on some targets, depending on - the CPU. -* Architectures prior to ARMv7 don't have atomic instructions. + the target, `target-cpu` and `target-feature`s. +* Older Arm architectures (e.g. Armv4, Armv5TE and Armv6-M) are limited to basic + [`load`][atomic-load] and [`store`][atomic-store] operations, and not more + advanced operations like [`fetch_add`][fetch-add] or + [`compare_exchange`][compare-exchange]. `alloc` is also supported, as long as you provide your own global allocator. Rust programs are output as ELF files. +[atomic-load]: https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicU32.html#method.load +[atomic-store]: https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicU32.html#method.store +[fetch-add]: https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicU32.html#method.fetch_add +[compare-exchange]: https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicU32.html#method.compare_exchange + ## Testing This is a cross-compiled target that you will need to emulate during testing. diff --git a/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md new file mode 100644 index 000000000000..f75194c815e0 --- /dev/null +++ b/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md @@ -0,0 +1,62 @@ +# `thumbv6m-none-eabi` + +**Tier: 2** + +Bare-metal target for CPUs in the [ARMv6-M] architecture family, supporting a +subset of the [T32 ISA][t32-isa]. + +Processors in this family include the: + +* [Arm Cortex-M0][cortex-m0] +* [Arm Cortex-M0+][cortex-m0plus] +* [Arm Cortex-M1][cortex-m1] + +See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all +`arm-none-eabi` targets. + +This target uses the soft-float ABI: functions which take `f32` or `f64` as +arguments will have those values packed into an integer registers. This is the +only option because there is no FPU support in [ARMv6-M]. + +[t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture +[ARMv6-M]: https://developer.arm.com/documentation/ddi0419/latest/ +[cortex-m0]: https://developer.arm.com/Processors/Cortex-M0 +[cortex-m0plus]: https://developer.arm.com/Processors/Cortex-M0+ +[cortex-m1]: https://developer.arm.com/Processors/Cortex-M1 + +## Target maintainers + +* [Rust Embedded Devices Working Group Cortex-M + Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org` + +## Target CPU and Target Feature options + +See [the bare-metal Arm +docs](arm-none-eabi.md#target-cpu-and-target-feature-options) for details on how +to use these flags. + +### Table of supported CPUs + +| CPU | FPU | Target CPU | Target Features | +| ---------- | --- | --------------- | --------------------- | +| Cortex-M0 | No | `cortex-m0` | None | +| Cortex-M0+ | No | `cortex-m0plus` | None | +| Cortex-M1 | No | `cortex-m1` | None | + +### Arm Cortex-M0 + +The target CPU option is `cortex-m0`. + +There are no relevant feature flags, and the FPU is not available. + +### Arm Cortex-M0+ + +The target CPU option is `cortex-m0plus`. + +There are no relevant feature flags, and the FPU is not available. + +### Arm Cortex-M1 + +The target CPU option is `cortex-m1`. + +There are no relevant feature flags, and the FPU is not available. diff --git a/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md new file mode 100644 index 000000000000..632f1681bb9c --- /dev/null +++ b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md @@ -0,0 +1,70 @@ +# `thumbv7em-none-eabi` + +**Tier: 2** + +Bare-metal target for CPUs in the [ARMv7E-M] architecture family, supporting a +subset of the [T32 ISA][t32-isa]. + +Processors in this family include the: + +* [Arm Cortex-M4][cortex-m4] and Arm Cortex-M4F +* [Arm Cortex-M7][cortex-m7] and Arm Cortex-M7F + +See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all +`arm-none-eabi` targets. + +This target uses the soft-float ABI: functions which take `f32` or `f64` as +arguments will have those values packed into an integer registers. This target +therefore does not require the use of an FPU (which is optional on Cortex-M4 and +Cortex-M7), but an FPU can be optionally enabled if desired. See also the +hard-float ABI version of this target +[`thumbv7em-none-eabihf`](thumbv7em-none-eabihf.md). + +[t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture +[ARMv7E-M]: https://developer.arm.com/documentation/ddi0403/latest/ +[cortex-m4]: https://developer.arm.com/Processors/Cortex-M4 +[cortex-m7]: https://developer.arm.com/Processors/Cortex-M7 + +## Target maintainers + +* [Rust Embedded Devices Working Group Cortex-M + Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org` + +## Target CPU and Target Feature options + +See [the bare-metal Arm +docs](arm-none-eabi.md#target-cpu-and-target-feature-options) for details on how +to use these flags. + +### Table of supported CPUs + +| CPU | FPU | DSP | Target CPU | Target Features | +| ---------- | --- | --- | ----------- | --------------- | +| Cortex-M4 | No | Yes | `cortex-m4` | `+soft-float` | +| Cortex-M4F | SP | Yes | `cortex-m4` | None | +| Cortex-M7 | No | Yes | `cortex-m7` | `+soft-float` | +| Cortex-M7F | SP | Yes | `cortex-m7` | `-fp64` | +| Cortex-M7F | DP | Yes | `cortex-m7` | None | + +### Arm Cortex-M4 and Arm Cortex-M4F + +The target CPU is `cortex-m4`. + +* All Cortex-M4 have DSP extensions + * support is controlled by the `dsp` *target-feature* + * enabled by default with this *target-cpu* +* Cortex-M4F has a single precision FPU + * support is enabled by default with this *target-cpu* + * disable support using the `+soft-float` feature + +### Arm Cortex-M7 and Arm Cortex-M7F + +The target CPU is `cortex-m7`. + +* All Cortex-M7 have DSP extensions + * support is controlled by the `dsp` *target-feature* + * enabled by default with this *target-cpu* +* Cortex-M7F have either a single-precision or double-precision FPU + * double-precision support is enabled by default with this *target-cpu* + * opt-out by using the `-f64` *target-feature* + * disable support entirely using the `+soft-float` feature diff --git a/src/doc/rustc/src/platform-support/thumbv7em-none-eabihf.md b/src/doc/rustc/src/platform-support/thumbv7em-none-eabihf.md new file mode 100644 index 000000000000..d4c93e3197c7 --- /dev/null +++ b/src/doc/rustc/src/platform-support/thumbv7em-none-eabihf.md @@ -0,0 +1,67 @@ +# `thumbv7em-none-eabihf` + +**Tier: 2** + +Bare-metal target for CPUs in the [ARMv7E-M] architecture family that have an +FPU, supporting a subset of the [T32 ISA][t32-isa]. + +Processors in this family include the: + +* [Arm Cortex-M4F][cortex-m4] +* [Arm Cortex-M7F][cortex-m7] + +See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all +`arm-none-eabi` targets. + +This target uses the hard-float ABI: functions which take `f32` or `f64` as +arguments will have them passed via FPU registers. This target therefore +requires the use of an FPU (which is optional on Cortex-M4 and Cortex-M7). See +also the soft-float ABI version of this target +[`thumbv7em-none-eabi`](thumbv7em-none-eabi.md). + +[t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture +[ARMv7E-M]: https://developer.arm.com/documentation/ddi0403/latest/ +[cortex-m4]: https://developer.arm.com/Processors/Cortex-M4 +[cortex-m7]: https://developer.arm.com/Processors/Cortex-M7 + +## Target maintainers + +* [Rust Embedded Devices Working Group Cortex-M + Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org` + +## Target CPU and Target Feature options + +See [the bare-metal Arm +docs](arm-none-eabi.md#target-cpu-and-target-feature-options) for details on how +to use these flags. + +### Table of supported CPUs + +| CPU | FPU | DSP | Target CPU | Target Features | +| ---------- | --- | --- | ----------- | --------------- | +| Cortex-M4F | SP | Yes | `cortex-m4` | None | +| Cortex-M7F | SP | Yes | `cortex-m7` | `-fp64` | +| Cortex-M7F | DP | Yes | `cortex-m7` | None | + +### Arm Cortex-M4 and Arm Cortex-M4F + +The target CPU is `cortex-m4`. + +* All Cortex-M4 have DSP extensions + * support is controlled by the `dsp` *target-feature* + * enabled by default with this *target-cpu* +* Cortex-M4F has a single precision FPU + * support is enabled by default with this *target* + * support is required when using the hard-float ABI + +### Arm Cortex-M7 and Arm Cortex-M7F + +The target CPU is `cortex-m7`. + +* All Cortex-M7 have DSP extensions + * support is controlled by the `dsp` *target-feature* + * enabled by default with this *target-cpu* +* Cortex-M7F have either a single-precision or double-precision FPU + * single precision support is enabled by default with this *target* + * double-precision support is enabled by default with this *target-cpu* + * opt-out by using the `-f64` *target-feature* diff --git a/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md new file mode 100644 index 000000000000..2c10f679f665 --- /dev/null +++ b/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md @@ -0,0 +1,44 @@ +# `thumbv7m-none-eabi` + +**Tier: 2** + +Bare-metal target for CPUs in the [ARMv7-M] architecture family, supporting a +subset of the [T32 ISA][t32-isa]. + +Processors in this family include the: + +* [Arm Cortex-M3][cortex-m3] + +See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all +`arm-none-eabi` targets. + +This target uses the soft-float ABI: functions which take `f32` or `f64` as +arguments will have those values packed into an integer registers. This is the +only option because there is no FPU support in [ARMv7-M]. + +[t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture +[ARMv7-M]: https://developer.arm.com/documentation/ddi0403/latest/ +[cortex-m3]: https://developer.arm.com/Processors/Cortex-M3 + +## Target maintainers + +* [Rust Embedded Devices Working Group Cortex-M + Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org` + +## Target CPU and Target Feature options + +See [the bare-metal Arm +docs](arm-none-eabi.md#target-cpu-and-target-feature-options) for details on how +to use these flags. + +### Table of supported CPUs + +| CPU | FPU | Target CPU | Target Features | +| ---------- | --- | ----------- | --------------------- | +| Cortex-M3 | No | `cortex-m3` | None | + +### Arm Cortex-M3 + +The target CPU option is `cortex-m3`. + +There are no relevant feature flags, and the FPU is not available. diff --git a/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md new file mode 100644 index 000000000000..6e9d2329aa92 --- /dev/null +++ b/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md @@ -0,0 +1,44 @@ +# `thumbv8m.base-none-eabi` + +**Tier: 2** + +Bare-metal target for CPUs in the Baseline [ARMv8-M] architecture family, +supporting a subset of the [T32 ISA][t32-isa]. + +Processors in this family include the: + +* [Arm Cortex-M23][cortex-m23] + +See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all +`arm-none-eabi` targets. + +This target uses the soft-float ABI: functions which take `f32` or `f64` as +arguments will have those values packed into an integer registers. This is the +only option because there is no FPU support in [ARMv6-M]. + +[t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture +[ARMv8-M]: https://developer.arm.com/documentation/ddi0553/latest/ +[cortex-m23]: https://developer.arm.com/Processors/Cortex-M23 + +## Target maintainers + +* [Rust Embedded Devices Working Group Cortex-M + Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org` + +## Target CPU and Target Feature options + +See [the bare-metal Arm +docs](arm-none-eabi.md#target-cpu-and-target-feature-options) for details on how +to use these flags. + +### Table of supported CPUs + +| CPU | FPU | Target CPU | Target Features | +| ----------- | --- | ------------ | --------------------- | +| Cortex-M23 | No | `cortex-m23` | None | + +### Arm Cortex-M23 + +The target CPU option is `cortex-m23`. + +There are no relevant feature flags, and the FPU is not available. diff --git a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md new file mode 100644 index 000000000000..eca9a7b1a701 --- /dev/null +++ b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md @@ -0,0 +1,124 @@ +# `thumbv8m.main-none-eabi` + +**Tier: 2** + +Bare-metal target for CPUs in the Mainline [ARMv8-M] architecture family, +supporting a subset of the [T32 ISA][t32-isa]. + +Processors in this family include the: + +* [Arm Cortex-M33][cortex-m33] +* [Arm Cortex-M35P][cortex-m35p] +* [Arm Cortex-M55][cortex-m55] +* [Arm Cortex-M85][cortex-m85] + +See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all +`arm-none-eabi` targets. + +This target uses the soft-float ABI: functions which take `f32` or `f64` as +arguments will have those values packed into an integer registers. This target +therefore does not require the use of an FPU (which is optional on Cortex-M33, +Cortex-M55 and Cortex-M85), but an FPU can be optionally enabled if desired. See +also the hard-float ABI version of this target +[`thumbv8m.main-none-eabihf`](thumbv7em-none-eabihf.md). + +[t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture +[ARMv8-M]: https://developer.arm.com/documentation/ddi0553/latest/ +[cortex-m33]: https://developer.arm.com/Processors/Cortex-M33 +[cortex-m35p]: https://developer.arm.com/Processors/Cortex-M35P +[cortex-m55]: https://developer.arm.com/Processors/Cortex-M55 +[cortex-m85]: https://developer.arm.com/Processors/Cortex-M85 + +## Target maintainers + +* [Rust Embedded Devices Working Group Cortex-M + Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org` + +## Target CPU and Target Feature options + +See [the bare-metal Arm +docs](arm-none-eabi.md#target-cpu-and-target-feature-options) for details on how +to use these flags. + +### Table of supported CPUs + +| CPU | FPU | DSP | MVE | Target CPU | Target Features | +| ----------- | --- | --- | --------- | ------------- | --------------------- | +| Cortex-M33 | No | No | N/A | `cortex-m33` | `+soft-float,-dsp` | +| Cortex-M33 | No | Yes | N/A | `cortex-m33` | `+soft-float` | +| Cortex-M33 | SP | No | N/A | `cortex-m33` | `-dsp` | +| Cortex-M33 | SP | Yes | N/A | `cortex-m33` | None | +| Cortex-M35P | No | No | N/A | `cortex-m35p` | `+soft-float,-dsp` | +| Cortex-M35P | No | Yes | N/A | `cortex-m35p` | `+soft-float` | +| Cortex-M35P | SP | No | N/A | `cortex-m35p` | `-dsp` | +| Cortex-M35P | SP | Yes | N/A | `cortex-m35p` | None | +| Cortex-M55 | No | Yes | No | `cortex-m55` | `+soft-float,-mve` | +| Cortex-M55 | DP | Yes | No | `cortex-m55` | `-mve` | +| Cortex-M55 | No | Yes | Int | `cortex-m55` | `+soft-float,-mve.fp` | +| Cortex-M55 | DP | Yes | Int | `cortex-m55` | `-mve.fp` | +| Cortex-M55 | DP | Yes | Int+Float | `cortex-m55` | None | +| Cortex-M85 | No | Yes | No | `cortex-m85` | `+soft-float,-mve` | +| Cortex-M85 | DP | Yes | No | `cortex-m85` | `-mve` | +| Cortex-M85 | No | Yes | Int | `cortex-m85` | `+soft-float,-mve.fp` | +| Cortex-M85 | DP | Yes | Int | `cortex-m85` | `-mve.fp` | +| Cortex-M85 | DP | Yes | Int+Float | `cortex-m85` | None | + +### Arm Cortex-M33 + +The target CPU is `cortex-m33`. + +* Has optional DSP extensions + * support is controlled by the `dsp` *target-feature* + * enabled by default with this *target-cpu* +* Has an optional single precision FPU + * support is enabled by default with this *target-cpu* + * disable support using the `+soft-float` feature + +### Arm Cortex-M35P + +The target CPU is `cortex-m35p`. + +* Has optional DSP extensions + * support is controlled by the `dsp` *target-feature* + * enabled by default with this *target-cpu* +* Has a single precision FPU + * support is enabled by default with this *target-cpu* + * disable support using the `+soft-float` feature + +### Arm Cortex-M55 + +The target CPU is `cortex-m55`. + +* Has DSP extensions + * support is controlled by the `dsp` *target-feature* + * enabled by default with this *target-cpu* +* Has an optional double-precision FPU that also supports half-precision FP16 + values + * support is enabled by default with this *target-cpu* + * disable support using the `+soft-float` feature +* Has optional support for M-Profile Vector Extensions + * Also known as *Helium Technology* + * Available with only integer support, or both integer/float support + * The appropriate feature for the MVE is either `mve` (integer) or `mve.fp` + (float) + * `mve.fp` is enabled by default on this target CPU + * disable using `-mve.fp` (disable float MVE) or `-mve` (disable all MVE) + +### Arm Cortex-M85 + +The target CPU is `cortex-m85`. + +* Has DSP extensions + * support is controlled by the `dsp` *target-feature* + * enabled by default with this *target-cpu* +* Has an optional double-precision FPU that also supports half-precision FP16 + values + * support is enabled by default with this *target-cpu* + * disable support using the `+soft-float` feature +* Has optional support for M-Profile Vector Extensions + * Also known as *Helium Technology* + * Available with only integer support, or both integer/float support + * The appropriate feature for the MVE is either `mve` (integer) or `mve.fp` + (float) + * `mve.fp` is enabled by default on this target CPU + * disable using `-mve.fp` (disable float MVE) or `-mve` (disable all MVE) diff --git a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabihf.md b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabihf.md new file mode 100644 index 000000000000..8f353a8d3db0 --- /dev/null +++ b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabihf.md @@ -0,0 +1,113 @@ +# `thumbv8m.main-none-eabihf` + +**Tier: 2** + +Bare-metal target for CPUs in the Mainline [ARMv8-M] architecture family, +supporting a subset of the [T32 ISA][t32-isa]. + +Processors in this family include the: + +* [Arm Cortex-M33F][cortex-m33] +* [Arm Cortex-M55F][cortex-m55] +* [Arm Cortex-M85F][cortex-m85] + +See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all +`arm-none-eabi` targets. + +This target uses the hard-float ABI: functions which take `f32` or `f64` as +arguments will have them passed via FPU registers. This target therefore +requires the use of an FPU (which is optional on Cortex-M33, Cortex-M55 and +Cortex-M85). See also the soft-float ABI version of this target +[`thumbv8m.main-none-eabi`](thumbv8m.main-none-eabi.md). + +[t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture +[ARMv8-M]: https://developer.arm.com/documentation/ddi0553/latest/ +[cortex-m33]: https://developer.arm.com/Processors/Cortex-M33 +[cortex-m55]: https://developer.arm.com/Processors/Cortex-M55 +[cortex-m85]: https://developer.arm.com/Processors/Cortex-M85 + +## Target maintainers + +* [Rust Embedded Devices Working Group Cortex-M + Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org` + +## Target CPU and Target Feature options + +See [the bare-metal Arm +docs](arm-none-eabi.md#target-cpu-and-target-feature-options) for details on how +to use these flags. + +### Table of supported CPUs + +| CPU | FPU | DSP | MVE | Target CPU | Target Features | +| ----------- | --- | --- | --------- | ------------- | --------------------- | +| Cortex-M33 | SP | No | N/A | `cortex-m33` | `-dsp` | +| Cortex-M33 | SP | Yes | N/A | `cortex-m33` | None | +| Cortex-M33P | SP | No | N/A | `cortex-m35p` | `-dsp` | +| Cortex-M33P | SP | Yes | N/A | `cortex-m35p` | None | +| Cortex-M55 | DP | Yes | No | `cortex-m55` | `-mve` | +| Cortex-M55 | DP | Yes | Int | `cortex-m55` | `-mve.fp` | +| Cortex-M55 | DP | Yes | Int+Float | `cortex-m55` | None | +| Cortex-M85 | DP | Yes | No | `cortex-m85` | `-mve` | +| Cortex-M85 | DP | Yes | Int | `cortex-m85` | `-mve.fp` | +| Cortex-M85 | DP | Yes | Int+Float | `cortex-m85` | None | + +### Arm Cortex-M33 + +The target CPU is `cortex-m33`. + +* Has optional DSP extensions + * support is controlled by the `dsp` *target-feature* + * enabled by default with this *target-cpu* +* Has an optional single precision FPU + * support is enabled by default with this *target-cpu* + * support is required when using the hard-float ABI + +### Arm Cortex-M35P + +The target CPU is `cortex-m35p`. + +* Has optional DSP extensions + * support is controlled by the `dsp` *target-feature* + * enabled by default with this *target-cpu* +* Has a single precision FPU + * support is enabled by default with this *target-cpu* + * support is required when using the hard-float ABI + +### Arm Cortex-M55 + +The target CPU is `cortex-m55`. + +* Has DSP extensions + * support is controlled by the `dsp` *target-feature* + * enabled by default with this *target-cpu* +* Has an optional double-precision FPU that also supports half-precision FP16 + values + * support is enabled by default with this *target-cpu* + * support is required when using the hard-float ABI +* Has optional support for M-Profile Vector Extensions + * Also known as *Helium Technology* + * Available with only integer support, or both integer/float support + * The appropriate feature for the MVE is either `mve` (integer) or `mve.fp` + (float) + * `mve.fp` is enabled by default on this target CPU + * disable using `-mve.fp` (disable float MVE) or `-mve` (disable all MVE) + +### Arm Cortex-M85 + +The target CPU is `cortex-m85`. + +* Has DSP extensions + * support is controlled by the `dsp` *target-feature* + * enabled by default with this *target-cpu* +* Has an optional double-precision FPU that also supports half-precision FP16 + values + * support is enabled by default with this *target-cpu* + * support is required when using the hard-float ABI +* Has optional support for M-Profile Vector Extensions + * Also known as *Helium Technology* + * Available with only integer support, or both integer/float support + * The appropriate feature for the MVE is either `mve` (integer) or `mve.fp` + (float) + * `mve.fp` is enabled by default on this target CPU + * disable using `-mve.fp` (disable float MVE) or `-mve` (disable all MVE) From babead5b586f8294b789a7fba252491b866aee61 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 26 Apr 2024 16:33:37 +0200 Subject: [PATCH 070/279] miri core/alloc tests: do not test a 2nd target --- src/bootstrap/mk/Makefile.in | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index 3cfd02407944..fc433bc5843b 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -53,15 +53,12 @@ check-aux: src/tools/cargotest \ $(BOOTSTRAP_ARGS) # Run standard library tests in Miri. - # We use a 64bit little-endian and a 32bit big-endian target for max coverage. $(Q)BOOTSTRAP_SKIP_TARGET_SANITY=1 \ $(BOOTSTRAP) miri --stage 2 \ - --target x86_64-unknown-linux-gnu,mips-unknown-linux-gnu \ library/core \ library/alloc \ --no-doc # Some doctests have intentional memory leaks. - # Also, they work only on the host. $(Q)MIRIFLAGS="-Zmiri-ignore-leaks -Zmiri-disable-isolation" \ $(BOOTSTRAP) miri --stage 2 \ library/core \ From 5b5ee0e7bd527d062143e5fe728d69f0f7e09bc9 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Fri, 26 Apr 2024 15:35:43 +0100 Subject: [PATCH 071/279] Remove unused `[patch]` for clippy_lints --- Cargo.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bbf4ecfe61d0..1379e4cd3bfd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,6 +112,3 @@ strip = true rustc-std-workspace-core = { path = 'library/rustc-std-workspace-core' } rustc-std-workspace-alloc = { path = 'library/rustc-std-workspace-alloc' } rustc-std-workspace-std = { path = 'library/rustc-std-workspace-std' } - -[patch."https://github.com/rust-lang/rust-clippy"] -clippy_lints = { path = "src/tools/clippy/clippy_lints" } From b17398490b0a6cb6b99cbf0d192e2952ae4f4b9b Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Fri, 26 Apr 2024 15:54:27 +0100 Subject: [PATCH 072/279] Fixed some typographical errors in arm-none-eabi.md. --- src/doc/rustc/src/platform-support/arm-none-eabi.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc/src/platform-support/arm-none-eabi.md b/src/doc/rustc/src/platform-support/arm-none-eabi.md index de41c5e676a8..4bd1d68fb755 100644 --- a/src/doc/rustc/src/platform-support/arm-none-eabi.md +++ b/src/doc/rustc/src/platform-support/arm-none-eabi.md @@ -43,7 +43,7 @@ FPU support. If a target ends if `eabihf`, that target uses the so-called *hard-float ABI*: functions which take `f32` or `f64` as arguments will have them passed via FPU -registers. These target therefore require the use of an FPU and will assume the +registers. These targets therefore require the use of an FPU and will assume the minimum support FPU for that architecture is available. More advanced FPU instructions (e.g. ones that work on double-precision `f64` values) may be generated if the code is compiled with a `target-cpu` or `target-feature` option @@ -66,10 +66,10 @@ scheduling and support for the features you do have. More details are available in the detailed target-specific documentation. **Note:** Many target-features are currently unstable and subject to change, and -if you use them you should dissassmble the compiler output and manually inspect +if you use them you should disassemble the compiler output and manually inspect it to ensure only appropriate instructions for your CPU have been generated. -If do you wish to use the *target-cpu* and *target-feature* options, you can add +If you wish to use the *target-cpu* and *target-feature* options, you can add them to your `.cargo/config.toml` file alongside any other flags your project uses (likely linker related ones): From 60c0fa1285cd0d87195d66ac4c80cd48de70aa9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Fri, 26 Apr 2024 17:20:16 +0200 Subject: [PATCH 073/279] crashes: add more tests --- tests/crashes/124262.rs | 5 +++++ tests/crashes/124340.rs | 17 +++++++++++++++++ tests/crashes/124342.rs | 6 ++++++ tests/crashes/124347.rs | 4 ++++ tests/crashes/124348.rs | 7 +++++++ tests/crashes/124350.rs | 17 +++++++++++++++++ tests/crashes/124352.rs | 4 ++++ tests/crashes/124375.rs | 11 +++++++++++ tests/crashes/92470.rs | 31 +++++++++++++++++++++++++++++++ 9 files changed, 102 insertions(+) create mode 100644 tests/crashes/124262.rs create mode 100644 tests/crashes/124340.rs create mode 100644 tests/crashes/124342.rs create mode 100644 tests/crashes/124347.rs create mode 100644 tests/crashes/124348.rs create mode 100644 tests/crashes/124350.rs create mode 100644 tests/crashes/124352.rs create mode 100644 tests/crashes/124375.rs create mode 100644 tests/crashes/92470.rs diff --git a/tests/crashes/124262.rs b/tests/crashes/124262.rs new file mode 100644 index 000000000000..b9dac5eca227 --- /dev/null +++ b/tests/crashes/124262.rs @@ -0,0 +1,5 @@ +//@ known-bug: #124262 +//@ edition:2021 + +struct Foo(<&[fn()] as ::core::ops::Deref>::Target); +const _: *const Foo = 0 as _; diff --git a/tests/crashes/124340.rs b/tests/crashes/124340.rs new file mode 100644 index 000000000000..cdf24fa03959 --- /dev/null +++ b/tests/crashes/124340.rs @@ -0,0 +1,17 @@ +//@ known-bug: #124340 +#![feature(anonymous_lifetime_in_impl_trait)] + +trait Producer { + type Output; + fn produce(self) -> Self::Output; +} + +trait SomeTrait<'a> {} + +fn force_same_lifetime<'a>(_x: &'a i32, _y: impl SomeTrait<'a>) { + unimplemented!() +} + +fn foo<'a>(s: &'a i32, producer: impl Producer>) { + force_same_lifetime(s, producer.produce()); +} diff --git a/tests/crashes/124342.rs b/tests/crashes/124342.rs new file mode 100644 index 000000000000..ae51b3db96f5 --- /dev/null +++ b/tests/crashes/124342.rs @@ -0,0 +1,6 @@ +//@ known-bug: #124342 +trait Trait2 : Trait { + reuse <() as Trait>::async { + (async || {}).await; + }; +} diff --git a/tests/crashes/124347.rs b/tests/crashes/124347.rs new file mode 100644 index 000000000000..d2bc555fe1c7 --- /dev/null +++ b/tests/crashes/124347.rs @@ -0,0 +1,4 @@ +//@ known-bug: #124347 +trait Trait: ToReuse { + reuse Trait::lolno { &self.0 }; +} diff --git a/tests/crashes/124348.rs b/tests/crashes/124348.rs new file mode 100644 index 000000000000..554f383026cb --- /dev/null +++ b/tests/crashes/124348.rs @@ -0,0 +1,7 @@ +//@ known-bug: #124348 +enum Eek { + TheConst, + UnusedByTheConst(Sum), +} + +const EEK_ZERO: &[Eek] = &[]; diff --git a/tests/crashes/124350.rs b/tests/crashes/124350.rs new file mode 100644 index 000000000000..d6038f280cf8 --- /dev/null +++ b/tests/crashes/124350.rs @@ -0,0 +1,17 @@ +//@ known-bug: #124350 + +struct Node {} + +impl Node +where + SmallVec<{ D * 2 }>:, +{ + fn new() -> Self { + let mut node = Node::new(); + (&a, 0)(); + + node + } +} + +struct SmallVec {} diff --git a/tests/crashes/124352.rs b/tests/crashes/124352.rs new file mode 100644 index 000000000000..e9eb4419e6a4 --- /dev/null +++ b/tests/crashes/124352.rs @@ -0,0 +1,4 @@ +//@ known-bug: #124352 +#![rustc_never_type_options(: Unsize = "hi")] + +fn main() {} diff --git a/tests/crashes/124375.rs b/tests/crashes/124375.rs new file mode 100644 index 000000000000..7165655178d7 --- /dev/null +++ b/tests/crashes/124375.rs @@ -0,0 +1,11 @@ +//@ known-bug: #124375 +//@ compile-flags: -Zmir-opt-level=0 +//@ only-x86_64 +#![crate_type = "lib"] +#![feature(naked_functions)] +use std::arch::asm; + +#[naked] +pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize { + asm!("lea rax, [rdi + rsi]", "ret", options(noreturn)); +} diff --git a/tests/crashes/92470.rs b/tests/crashes/92470.rs new file mode 100644 index 000000000000..a3c518f5ec62 --- /dev/null +++ b/tests/crashes/92470.rs @@ -0,0 +1,31 @@ +//@ known-bug: #92470 +fn main() { + encode(&mut EncoderImpl); +} + +pub trait Encoder { + type W; + + fn writer(&self) -> Self::W; +} + +fn encode(mut encoder: E) { + encoder.writer(); + encode(&mut encoder); +} + +struct EncoderImpl; + +impl Encoder for EncoderImpl { + type W = (); + + fn writer(&self) {} +} + +impl<'a, T: Encoder> Encoder for &'a mut T { + type W = T::W; + + fn writer(&self) -> Self::W { + panic!() + } +} From c47978a241ac1dd512b2ed7d146c1e1a71326dec Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 26 Apr 2024 17:55:10 +0200 Subject: [PATCH 074/279] PathBuf: replace transmuting by accessor functions --- library/std/src/ffi/os_str.rs | 6 ++++++ library/std/src/path.rs | 8 +------- library/std/src/sys/os_str/bytes.rs | 6 ++++++ library/std/src/sys/os_str/wtf8.rs | 6 ++++++ library/std/src/sys_common/wtf8.rs | 6 ++++++ 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 20ebe1c4f8a0..9dd3d7d3fa16 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -532,6 +532,12 @@ impl OsString { let rw = Box::into_raw(self.inner.into_box()) as *mut OsStr; unsafe { Box::from_raw(rw) } } + + /// Part of a hack to make PathBuf::push/pop more efficient. + #[inline] + pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec { + self.inner.as_mut_vec_for_path_buf() + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 1c58671a0cf7..85355435100c 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1158,12 +1158,6 @@ impl FusedIterator for Ancestors<'_> {} /// Which method works best depends on what kind of situation you're in. #[cfg_attr(not(test), rustc_diagnostic_item = "PathBuf")] #[stable(feature = "rust1", since = "1.0.0")] -// `PathBuf::as_mut_vec` current implementation relies -// on `PathBuf` being layout-compatible with `Vec`. -// However, `PathBuf` layout is considered an implementation detail and must not be relied upon. We -// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under -// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy. -#[cfg_attr(not(doc), repr(transparent))] pub struct PathBuf { inner: OsString, } @@ -1171,7 +1165,7 @@ pub struct PathBuf { impl PathBuf { #[inline] fn as_mut_vec(&mut self) -> &mut Vec { - unsafe { &mut *(self as *mut PathBuf as *mut Vec) } + self.inner.as_mut_vec_for_path_buf() } /// Allocates an empty `PathBuf`. diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs index 4ca3f1cd1853..3076e18b237d 100644 --- a/library/std/src/sys/os_str/bytes.rs +++ b/library/std/src/sys/os_str/bytes.rs @@ -198,6 +198,12 @@ impl Buf { pub fn into_rc(&self) -> Rc { self.as_slice().into_rc() } + + /// Part of a hack to make PathBuf::push/pop more efficient. + #[inline] + pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec { + &mut self.inner + } } impl Slice { diff --git a/library/std/src/sys/os_str/wtf8.rs b/library/std/src/sys/os_str/wtf8.rs index 352bd7359033..b3ceb55802dc 100644 --- a/library/std/src/sys/os_str/wtf8.rs +++ b/library/std/src/sys/os_str/wtf8.rs @@ -158,6 +158,12 @@ impl Buf { pub fn into_rc(&self) -> Rc { self.as_slice().into_rc() } + + /// Part of a hack to make PathBuf::push/pop more efficient. + #[inline] + pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec { + self.inner.as_mut_vec_for_path_buf() + } } impl Slice { diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs index 2dbd19d71719..38e15f9f5496 100644 --- a/library/std/src/sys_common/wtf8.rs +++ b/library/std/src/sys_common/wtf8.rs @@ -468,6 +468,12 @@ impl Wtf8Buf { let bytes: Box<[u8]> = unsafe { mem::transmute(boxed) }; Wtf8Buf { bytes: bytes.into_vec(), is_known_utf8: false } } + + /// Part of a hack to make PathBuf::push/pop more efficient. + #[inline] + pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec { + &mut self.bytes + } } /// Creates a new WTF-8 string from an iterator of code points. From 1367827eac3d813a261a4c444037af9736996daa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 26 Apr 2024 17:24:06 +0000 Subject: [PATCH 075/279] remove extraneous note on `UnableToRunDsymutil` diagnostic --- compiler/rustc_codegen_ssa/src/errors.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index b843d1bdf235..ed6a0c244106 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -431,7 +431,6 @@ pub struct ProcessingDymutilFailed { #[derive(Diagnostic)] #[diag(codegen_ssa_unable_to_run_dsymutil)] -#[note] pub struct UnableToRunDsymutil { pub error: Error, } From 74cbc09fc914961d98a64e203b9a6dbc8bc00375 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 25 Apr 2024 20:39:17 +0200 Subject: [PATCH 076/279] Port run-make `--print=native-static-libs` to rmake.rs --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../print-native-static-libs/Makefile | 19 ------ .../print-native-static-libs/rmake.rs | 63 +++++++++++++++++++ 3 files changed, 63 insertions(+), 20 deletions(-) delete mode 100644 tests/run-make/print-native-static-libs/Makefile create mode 100644 tests/run-make/print-native-static-libs/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 9b3c0d0f1a57..1b560ee352c6 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -220,7 +220,6 @@ run-make/pretty-print-to-file/Makefile run-make/pretty-print-with-dep-file/Makefile run-make/print-calling-conventions/Makefile run-make/print-cfg/Makefile -run-make/print-native-static-libs/Makefile run-make/print-target-list/Makefile run-make/profile/Makefile run-make/prune-link-args/Makefile diff --git a/tests/run-make/print-native-static-libs/Makefile b/tests/run-make/print-native-static-libs/Makefile deleted file mode 100644 index a16c8b0f2a40..000000000000 --- a/tests/run-make/print-native-static-libs/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -include ../tools.mk - -# ignore-cross-compile -# ignore-wasm - -all: - $(RUSTC) --crate-type rlib -lbar_cli bar.rs - $(RUSTC) foo.rs -lfoo_cli -lfoo_cli --crate-type staticlib --print native-static-libs 2>&1 \ - | grep 'note: native-static-libs: ' \ - | sed 's/note: native-static-libs: \(.*\)/\1/' > $(TMPDIR)/libs.txt - - cat $(TMPDIR)/libs.txt | grep -F "glib-2.0" # in bar.rs - cat $(TMPDIR)/libs.txt | grep -F "systemd" # in foo.rs - cat $(TMPDIR)/libs.txt | grep -F "bar_cli" - cat $(TMPDIR)/libs.txt | grep -F "foo_cli" - - # make sure that foo_cli and glib-2.0 are not consecutively present - cat $(TMPDIR)/libs.txt | grep -Fv "foo_cli -lfoo_cli" - cat $(TMPDIR)/libs.txt | grep -Fv "glib-2.0 -lglib-2.0" diff --git a/tests/run-make/print-native-static-libs/rmake.rs b/tests/run-make/print-native-static-libs/rmake.rs new file mode 100644 index 000000000000..efc51d276efc --- /dev/null +++ b/tests/run-make/print-native-static-libs/rmake.rs @@ -0,0 +1,63 @@ +//! This checks the output of `--print=native-static-libs` +//! +//! Specifically, this test makes sure that one and only one +//! note is emitted with the text "native-static-libs:" as prefix +//! that the note contains the link args given in the source code +//! and cli of the current crate and downstream crates. +//! +//! It also checks that there aren't any duplicated consecutive +//! args, as they are useless and suboptimal for debugability. +//! See https://github.com/rust-lang/rust/issues/113209. + +//@ ignore-cross-compile +//@ ignore-wasm + +extern crate run_make_support; + +use std::io::BufRead; + +use run_make_support::rustc; + +fn main() { + // build supporting crate + rustc() + .input("bar.rs") + .crate_type("rlib") + .arg("-lbar_cli") + .run(); + + // build main crate as staticlib + let output = rustc() + .input("foo.rs") + .crate_type("staticlib") + .arg("-lfoo_cli") + .arg("-lfoo_cli") // 2nd time + .print("native-static-libs") + .run(); + + let mut found_note = false; + for l in output.stderr.lines() { + let l = l.expect("utf-8 string"); + + let Some(args) = l.strip_prefix("note: native-static-libs:") else { continue; }; + assert!(!found_note); + found_note = true; + + let args: Vec<&str> = args.trim().split_ascii_whitespace().collect(); + + assert!(args.contains(&"-lglib-2.0")); // in bar.rs + assert!(args.contains(&"-lsystemd")); // in foo.rs + assert!(args.contains(&"-lbar_cli")); + assert!(args.contains(&"-lfoo_cli")); + + // make sure that no args are consecutively present + let dedup_args: Vec<&str> = { + let mut args = args.clone(); + args.dedup(); + args + }; + assert_eq!(args, dedup_args); + } + + assert!(found_note); +} From c5eda4199cf88b6de86da269970c0aa4b7f4350c Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 26 Apr 2024 13:53:34 -0400 Subject: [PATCH 077/279] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index c9392675917a..b60a15551551 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit c9392675917adc2edab269eea27c222b5359c637 +Subproject commit b60a1555155111e962018007a6d0ef85207db463 From 23b67de1513f412d0df37ece3bd90a3fd653c444 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Fri, 26 Apr 2024 20:48:15 +0200 Subject: [PATCH 078/279] Document never type fallback in `!`'s docs --- library/core/src/primitive_docs.rs | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index bda1ee6f4571..99b132fe3996 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -268,6 +268,47 @@ mod prim_bool {} /// [`Debug`]: fmt::Debug /// [`default()`]: Default::default /// +/// # Never type fallback +/// +/// When the compiler sees a value of type `!` it implicitly inserts a coercion (if possible), +/// to allow type check to infer any type: +/// +/// ```rust,ignore (illustrative-and-has-placeholders) +/// // this +/// let x: u8 = panic!(); +/// +/// // is (essentially) turned by the compiler into +/// let x: u8 = absurd(panic!()); +/// +/// // where absurd is a function with the following signature +/// // (it's sound, because `!` always marks unreachable code): +/// fn absurd(_: !) -> T { ... } +// FIXME: use `core::convert::absurd` here instead, once it's merged +/// ``` +/// +/// While it's convenient to be able to use non-diverging code in one of the branches (like +/// `if a { b } else { return }`) this could lead to compilation errors: +/// +/// ```compile_fail +/// // this +/// { panic!() }; +/// +/// // gets turned into this +/// { absurd(panic!()) }; // error: can't infer the type of `absurd` +/// ``` +/// +/// To prevent such errors, compiler remembers where it inserted `absurd` calls, and if it can't +/// infer their type, it sets the type to the fallback type. `{ absurd::(panic!()) };`. +/// This is what is known as "never type fallback". +/// +/// Historically fallback was [`()`], causing confusing behavior where `!` spontaneously coerced +/// to `()`, even though `()` was never mentioned (because of the fallback). There are plans to +/// change it in 2024 edition (and possibly in all editions on a later date), see +/// [Tracking Issue for making `!` fall back to `!`][fallback-ti]. +/// +/// [`()`]: prim@unit +/// [fallback-ti]: https://github.com/rust-lang/rust/issues/123748 +/// #[unstable(feature = "never_type", issue = "35121")] mod prim_never {} From 7688f798d543039387d87401889b75e9305a7a6d Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 27 Apr 2024 00:26:06 +0200 Subject: [PATCH 079/279] Also support MSVC in print-native-static-libs test --- .../print-native-static-libs/rmake.rs | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/tests/run-make/print-native-static-libs/rmake.rs b/tests/run-make/print-native-static-libs/rmake.rs index efc51d276efc..fc8701777d12 100644 --- a/tests/run-make/print-native-static-libs/rmake.rs +++ b/tests/run-make/print-native-static-libs/rmake.rs @@ -16,7 +16,7 @@ extern crate run_make_support; use std::io::BufRead; -use run_make_support::rustc; +use run_make_support::{rustc, is_msvc}; fn main() { // build supporting crate @@ -45,10 +45,23 @@ fn main() { let args: Vec<&str> = args.trim().split_ascii_whitespace().collect(); - assert!(args.contains(&"-lglib-2.0")); // in bar.rs - assert!(args.contains(&"-lsystemd")); // in foo.rs - assert!(args.contains(&"-lbar_cli")); - assert!(args.contains(&"-lfoo_cli")); + macro_rules! assert_contains_lib { + ($lib:literal in $args:ident) => {{ + let lib = format!( + "{}{}{}", + if !is_msvc() { "-l" } else { "" }, + $lib, + if !is_msvc() { "" } else { ".lib" }, + ); + let found = $args.contains(&&*lib); + assert!(found, "unable to find lib `{}` in those linker args: {:?}", lib, $args); + }} + } + + assert_contains_lib!("glib-2.0" in args); // in bar.rs + assert_contains_lib!("systemd" in args); // in foo.rs + assert_contains_lib!("bar_cli" in args); + assert_contains_lib!("foo_cli" in args); // make sure that no args are consecutively present let dedup_args: Vec<&str> = { From b73bfd26e4ddd6e91debf86cbaeb060e7fbb4425 Mon Sep 17 00:00:00 2001 From: Waffle Maybe Date: Sat, 27 Apr 2024 00:47:23 +0200 Subject: [PATCH 080/279] Apply suggestions from code review Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com> --- library/core/src/primitive_docs.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 99b132fe3996..1839c56f16dd 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -270,8 +270,8 @@ mod prim_bool {} /// /// # Never type fallback /// -/// When the compiler sees a value of type `!` it implicitly inserts a coercion (if possible), -/// to allow type check to infer any type: +/// When the compiler sees a value of type `!` it implicitly inserts a coercion (if possible) +/// to allow type checker to infer any type: /// /// ```rust,ignore (illustrative-and-has-placeholders) /// // this @@ -297,8 +297,13 @@ mod prim_bool {} /// { absurd(panic!()) }; // error: can't infer the type of `absurd` /// ``` /// -/// To prevent such errors, compiler remembers where it inserted `absurd` calls, and if it can't -/// infer their type, it sets the type to the fallback type. `{ absurd::(panic!()) };`. +/// To prevent such errors, the compiler remembers where it inserted `absurd` calls, and +/// if it can't infer their type, it sets the type to the fallback type: +/// ```rust, ignore +/// type Fallback = /* An arbitrarily selected type! */; +/// { absurd::(panic!()) } +/// ``` +/// /// This is what is known as "never type fallback". /// /// Historically fallback was [`()`], causing confusing behavior where `!` spontaneously coerced From c63b0ceb94c4c953f080ff0c543a950737408ff7 Mon Sep 17 00:00:00 2001 From: Jubilee <46493976+workingjubilee@users.noreply.github.com> Date: Fri, 26 Apr 2024 18:28:46 -0700 Subject: [PATCH 081/279] thread_local: refine LazyKeyInner::take safety doc Co-authored-by: joboet --- library/std/src/sys/thread_local/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index 4fcea052ed0a..7500c95d8b47 100644 --- a/library/std/src/sys/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs @@ -94,7 +94,7 @@ mod lazy { /// Watch out: unsynchronized internal mutability! /// /// # Safety - /// Unsound if called while any `&'static T` is active. + /// Causes UB if any reference to the value is used after this. #[allow(unused)] pub(crate) unsafe fn take(&self) -> Option { let mutable: *mut _ = UnsafeCell::get(&self.inner); From 82cc02a60bc09e31afa6cead8994a9e86b2a8012 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 26 Apr 2024 22:51:16 -0400 Subject: [PATCH 082/279] Do not ICE on invalid consts when walking mono-reachable blocks --- compiler/rustc_middle/src/mir/mod.rs | 9 ++---- .../ui/consts/mono-reachable-invalid-const.rs | 23 +++++++++++++++ .../mono-reachable-invalid-const.stderr | 29 +++++++++++++++++++ 3 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 tests/ui/consts/mono-reachable-invalid-const.rs create mode 100644 tests/ui/consts/mono-reachable-invalid-const.stderr diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 43e4e8216e1a..8555aa48c306 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -701,10 +701,7 @@ impl<'tcx> Body<'tcx> { env, crate::ty::EarlyBinder::bind(constant.const_), ); - let Some(bits) = mono_literal.try_eval_bits(tcx, env) else { - bug!("Couldn't evaluate constant {:?} in mono {:?}", constant, instance); - }; - bits + mono_literal.try_eval_bits(tcx, env) }; let TerminatorKind::SwitchInt { discr, targets } = &block.terminator().kind else { @@ -714,7 +711,7 @@ impl<'tcx> Body<'tcx> { // If this is a SwitchInt(const _), then we can just evaluate the constant and return. let discr = match discr { Operand::Constant(constant) => { - let bits = eval_mono_const(constant); + let bits = eval_mono_const(constant)?; return Some((bits, targets)); } Operand::Move(place) | Operand::Copy(place) => place, @@ -748,7 +745,7 @@ impl<'tcx> Body<'tcx> { match rvalue { Rvalue::NullaryOp(NullOp::UbChecks, _) => Some((tcx.sess.ub_checks() as u128, targets)), Rvalue::Use(Operand::Constant(constant)) => { - let bits = eval_mono_const(constant); + let bits = eval_mono_const(constant)?; Some((bits, targets)) } _ => None, diff --git a/tests/ui/consts/mono-reachable-invalid-const.rs b/tests/ui/consts/mono-reachable-invalid-const.rs new file mode 100644 index 000000000000..aabdb071bc9f --- /dev/null +++ b/tests/ui/consts/mono-reachable-invalid-const.rs @@ -0,0 +1,23 @@ +//@ build-fail + +struct Bar; + +impl Bar { + const ASSERT: bool = { + let b = std::convert::identity(1); + ["oops"][b]; //~ ERROR evaluation of `Bar::<0>::ASSERT` failed + true + }; + + fn assert() { + let val = Self::ASSERT; + if val { + std::convert::identity(val); + } + } +} + + +fn main() { + Bar::<0>::assert(); +} diff --git a/tests/ui/consts/mono-reachable-invalid-const.stderr b/tests/ui/consts/mono-reachable-invalid-const.stderr new file mode 100644 index 000000000000..6b7b25b59b82 --- /dev/null +++ b/tests/ui/consts/mono-reachable-invalid-const.stderr @@ -0,0 +1,29 @@ +error[E0080]: evaluation of `Bar::<0>::ASSERT` failed + --> $DIR/mono-reachable-invalid-const.rs:8:9 + | +LL | ["oops"][b]; + | ^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1 + +note: erroneous constant encountered + --> $DIR/mono-reachable-invalid-const.rs:13:19 + | +LL | let val = Self::ASSERT; + | ^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/mono-reachable-invalid-const.rs:13:19 + | +LL | let val = Self::ASSERT; + | ^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +note: the above error was encountered while instantiating `fn Bar::<0>::assert` + --> $DIR/mono-reachable-invalid-const.rs:22:5 + | +LL | Bar::<0>::assert(); + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. From c62bc31b16f2e80e976dbd193dc785c466c2c55f Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Sat, 27 Apr 2024 09:36:38 +0530 Subject: [PATCH 083/279] Fix ICE on invalid const param types --- compiler/rustc_hir_analysis/src/collect.rs | 2 + tests/crashes/123863.rs | 6 --- .../ui/typeck/ice-unexpected-region-123863.rs | 9 +++++ .../ice-unexpected-region-123863.stderr | 38 +++++++++++++++++++ 4 files changed, 49 insertions(+), 6 deletions(-) delete mode 100644 tests/crashes/123863.rs create mode 100644 tests/ui/typeck/ice-unexpected-region-123863.rs create mode 100644 tests/ui/typeck/ice-unexpected-region-123863.stderr diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 599f25147ce3..0f0736f87568 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -386,6 +386,8 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { fn ct_infer(&self, ty: Ty<'tcx>, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> { let ty = self.tcx.fold_regions(ty, |r, _| match *r { + rustc_type_ir::RegionKind::ReStatic => r, + // This is never reached in practice. If it ever is reached, // `ReErased` should be changed to `ReStatic`, and any other region // left alone. diff --git a/tests/crashes/123863.rs b/tests/crashes/123863.rs deleted file mode 100644 index e0f3ac9dcd72..000000000000 --- a/tests/crashes/123863.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: #123863 -const fn concat_strs() -> &'static str { - struct Inner; - Inner::concat_strs::<"a">::A -} -pub fn main() {} diff --git a/tests/ui/typeck/ice-unexpected-region-123863.rs b/tests/ui/typeck/ice-unexpected-region-123863.rs new file mode 100644 index 000000000000..d0242df5fd2f --- /dev/null +++ b/tests/ui/typeck/ice-unexpected-region-123863.rs @@ -0,0 +1,9 @@ +const fn concat_strs() -> &'static str { +//~^ ERROR &'static str` is forbidden as the type of a const generic parameter + struct Inner; +//~^ ERROR &'static str` is forbidden as the type of a const generic parameter + Inner::concat_strs::<"a">::A +//~^ ERROR ambiguous associated type +} + +pub fn main() {} diff --git a/tests/ui/typeck/ice-unexpected-region-123863.stderr b/tests/ui/typeck/ice-unexpected-region-123863.stderr new file mode 100644 index 000000000000..08f1ede95b45 --- /dev/null +++ b/tests/ui/typeck/ice-unexpected-region-123863.stderr @@ -0,0 +1,38 @@ +error: `&'static str` is forbidden as the type of a const generic parameter + --> $DIR/ice-unexpected-region-123863.rs:1:31 + | +LL | const fn concat_strs() -> &'static str { + | ^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` +help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + | +LL + #![feature(adt_const_params)] + | + +error: `&'static str` is forbidden as the type of a const generic parameter + --> $DIR/ice-unexpected-region-123863.rs:3:27 + | +LL | struct Inner; + | ^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` +help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + | +LL + #![feature(adt_const_params)] + | + +error[E0223]: ambiguous associated type + --> $DIR/ice-unexpected-region-123863.rs:5:5 + | +LL | Inner::concat_strs::<"a">::A + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `concat_strs` implemented for `Inner<_>`, you could use the fully-qualified path + | +LL | as Example>::concat_strs::A + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0223`. From fc73b4c34488b92d6e6af32e063a39e000cd073b Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Sat, 27 Apr 2024 11:02:15 +0530 Subject: [PATCH 084/279] Add missing tests for an ICE --- .../const-eval/ice-unhandled-type-122191.rs | 18 ++++++ .../ice-unhandled-type-122191.stderr | 58 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 tests/ui/consts/const-eval/ice-unhandled-type-122191.rs create mode 100644 tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr diff --git a/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs b/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs new file mode 100644 index 000000000000..a92b99976e26 --- /dev/null +++ b/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs @@ -0,0 +1,18 @@ +type Foo = impl Send; +//~^ ERROR `impl Trait` in type aliases is unstable + +struct A; + +const VALUE: Foo = value(); +//~^ ERROR cannot find function `value` in this scope + +fn test() { + match VALUE { + 0 | 0 => {} +//~^ ERROR mismatched types +//~| ERROR mismatched types + _ => (), + } +} + +fn main() {} diff --git a/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr b/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr new file mode 100644 index 000000000000..daf0ccaa776c --- /dev/null +++ b/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr @@ -0,0 +1,58 @@ +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/ice-unhandled-type-122191.rs:1:12 + | +LL | type Foo = impl Send; + | ^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(type_alias_impl_trait)]` 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[E0425]: cannot find function `value` in this scope + --> $DIR/ice-unhandled-type-122191.rs:6:20 + | +LL | const VALUE: Foo = value(); + | ^^^^^ not found in this scope + +error[E0308]: mismatched types + --> $DIR/ice-unhandled-type-122191.rs:11:9 + | +LL | type Foo = impl Send; + | --------- the expected opaque type +... +LL | match VALUE { + | ----- this expression has type `Foo` +LL | 0 | 0 => {} + | ^ expected opaque type, found integer + | + = note: expected opaque type `Foo` + found type `{integer}` +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/ice-unhandled-type-122191.rs:9:4 + | +LL | fn test() { + | ^^^^ + +error[E0308]: mismatched types + --> $DIR/ice-unhandled-type-122191.rs:11:13 + | +LL | type Foo = impl Send; + | --------- the expected opaque type +... +LL | match VALUE { + | ----- this expression has type `Foo` +LL | 0 | 0 => {} + | ^ expected opaque type, found integer + | + = note: expected opaque type `Foo` + found type `{integer}` +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/ice-unhandled-type-122191.rs:9:4 + | +LL | fn test() { + | ^^^^ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0308, E0425, E0658. +For more information about an error, try `rustc --explain E0308`. From 6b6bc9805ddeebf35fec63844e6f00f06059650a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 26 Apr 2024 19:04:23 +0200 Subject: [PATCH 085/279] io safety: update Unix explanation --- library/std/src/io/mod.rs | 2 +- library/std/src/os/unix/io/mod.rs | 31 +++++++++++++++++++++---------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 98973a43e1de..a3fdcdc2d07b 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -266,7 +266,7 @@ //! its file descriptors with no operations being performed by any other part of the program. //! //! Note that exclusive ownership of a file descriptor does *not* imply exclusive ownership of the -//! underlying kernel object that the file descriptor references (also called "file description" on +//! underlying kernel object that the file descriptor references (also called "open file description" on //! some operating systems). File descriptors basically work like [`Arc`]: when you receive an owned //! file descriptor, you cannot know whether there are any other file descriptors that reference the //! same kernel object. However, when you create a new kernel object, you know that you are holding diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs index 827278f8b260..6d4090ee31cf 100644 --- a/library/std/src/os/unix/io/mod.rs +++ b/library/std/src/os/unix/io/mod.rs @@ -12,8 +12,8 @@ //! | Type | Analogous to | //! | ------------------ | ------------ | //! | [`RawFd`] | `*const _` | -//! | [`BorrowedFd<'a>`] | `&'a _` | -//! | [`OwnedFd`] | `Box<_>` | +//! | [`BorrowedFd<'a>`] | `&'a Arc<_>` | +//! | [`OwnedFd`] | `Arc<_>` | //! //! Like raw pointers, `RawFd` values are primitive values. And in new code, //! they should be considered unsafe to do I/O on (analogous to dereferencing @@ -23,22 +23,31 @@ //! either by adding `unsafe` to APIs that dereference `RawFd` values, or by //! using to `BorrowedFd` or `OwnedFd` instead. //! +//! The use of `Arc` for borrowed/owned file descriptors may be surprising. Unix file descriptors +//! are mere references to internal kernel objects called "open file descriptions", and the same +//! open file description can be referenced by multiple file descriptors (e.g. if `dup` is used). +//! State such as the offset within the file is shared among all file descriptors that refer to the +//! same open file description, and the kernel internally does reference-counting to only close the +//! underlying resource once all file descriptors referencing it are closed. That's why `Arc` (and +//! not `Box`) is the closest Rust analogy to an "owned" file descriptor. +//! //! Like references, `BorrowedFd` values are tied to a lifetime, to ensure //! that they don't outlive the resource they point to. These are safe to //! use. `BorrowedFd` values may be used in APIs which provide safe access to //! any system call except for: //! //! - `close`, because that would end the dynamic lifetime of the resource -//! without ending the lifetime of the file descriptor. +//! without ending the lifetime of the file descriptor. (Equivalently: +//! an `&Arc<_>` cannot be `drop`ed.) //! //! - `dup2`/`dup3`, in the second argument, because this argument is -//! closed and assigned a new resource, which may break the assumptions +//! closed and assigned a new resource, which may break the assumptions of //! other code using that file descriptor. //! -//! `BorrowedFd` values may be used in APIs which provide safe access to `dup` -//! system calls, so types implementing `AsFd` or `From` should not -//! assume they always have exclusive access to the underlying file -//! description. +//! `BorrowedFd` values may be used in APIs which provide safe access to `dup` system calls, so code +//! working with `OwnedFd` cannot assume to have exclusive access to the underlying open file +//! description. (Equivalently: `&Arc` may be used in APIs that provide safe access to `clone`, so +//! code working with an `Arc` cannot assume that the reference count is 1.) //! //! `BorrowedFd` values may also be used with `mmap`, since `mmap` uses the //! provided file descriptor in a manner similar to `dup` and does not require @@ -52,8 +61,10 @@ //! take full responsibility for ensuring that safe Rust code cannot evoke //! undefined behavior through it. //! -//! Like boxes, `OwnedFd` values conceptually own the resource they point to, -//! and free (close) it when they are dropped. +//! Like `Arc`, `OwnedFd` values conceptually own one reference to the resource they point to, +//! and decrement the reference count when they are dropped (by calling `close`). +//! When the reference count reaches 0, the underlying open file description will be freed +//! by the kernel. //! //! See the [`io` module docs][io-safety] for a general explanation of I/O safety. //! From 411607bec493ac02c6038714561b52008f097a02 Mon Sep 17 00:00:00 2001 From: klensy Date: Thu, 25 Apr 2024 13:17:29 +0300 Subject: [PATCH 086/279] tests: remove some trailing ws --- compiler/rustc_errors/src/emitter.rs | 16 ++++++++++++--- .../huge_multispan_highlight.svg | 20 +++++++++---------- tests/ui/error-emitter/highlighting.svg | 10 +++++----- .../ui/error-emitter/highlighting.windows.svg | 10 +++++----- .../multiline-multipart-suggestion.svg | 10 +++++----- ...multiline-multipart-suggestion.windows.svg | 10 +++++----- tests/ui/imports/issue-59764.stderr | 4 ++-- tests/ui/issues/issue-22644.stderr | 4 ++-- tests/ui/lint/use_suggestion_json.stderr | 2 +- tests/ui/macros/issue-118048.stderr | 2 +- tests/ui/methods/method-call-err-msg.stderr | 2 +- tests/ui/str/str-escape.stderr | 4 ++-- .../struct-rec/issue-17431-2.stderr | 2 +- .../struct-rec/mutual-struct-recursion.stderr | 4 ++-- tests/ui/suggestions/issue-99240-2.stderr | 2 +- tests/ui/typeck/issue-100285.stderr | 2 +- tests/ui/typeck/issue-31173.stderr | 2 +- ...oxed-closure-sugar-lifetime-elision.stderr | 2 +- .../variance-regions-unused-indirect.stderr | 2 +- 19 files changed, 60 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 6ce3fa3535dc..74852ba36985 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -984,7 +984,7 @@ impl HumanEmitter { // 4 | } // | for pos in 0..=line_len { - draw_col_separator(buffer, line_offset + pos + 1, width_offset - 2); + draw_col_separator_no_space(buffer, line_offset + pos + 1, width_offset - 2); } // Write the horizontal lines for multiline annotations @@ -2260,13 +2260,23 @@ impl HumanEmitter { buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); } [] => { - draw_col_separator(buffer, *row_num, max_line_num_len + 1); + draw_col_separator_no_space(buffer, *row_num, max_line_num_len + 1); } _ => { buffer.puts(*row_num, max_line_num_len + 1, "~ ", Style::Addition); } } - buffer.append(*row_num, &normalize_whitespace(line_to_add), Style::NoStyle); + // LL | line_to_add + // ++^^^ + // | | + // | magic `3` + // `max_line_num_len` + buffer.puts( + *row_num, + max_line_num_len + 3, + &normalize_whitespace(line_to_add), + Style::NoStyle, + ); } else if let DisplaySuggestion::Add = show_code_change { buffer.puts(*row_num, 0, &self.maybe_anonymized(line_num), Style::LineNumber); buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); diff --git a/tests/ui/codemap_tests/huge_multispan_highlight.svg b/tests/ui/codemap_tests/huge_multispan_highlight.svg index f1e96583ff06..7b6dbb17c6f9 100644 --- a/tests/ui/codemap_tests/huge_multispan_highlight.svg +++ b/tests/ui/codemap_tests/huge_multispan_highlight.svg @@ -27,11 +27,11 @@ LL | let _ = match true { - | ---------- `match` arms have incompatible types + | ---------- `match` arms have incompatible types LL | true => ( - | _________________- + | _________________- LL | | // last line shown in multispan header @@ -41,11 +41,11 @@ LL | | ), - | |_________- this is found to be of type `()` + | |_________- this is found to be of type `()` LL | false => " - | __________________^ + | __________________^ ... | @@ -53,7 +53,7 @@ LL | | ", - | |_________^ expected `()`, found `&str` + | |_________^ expected `()`, found `&str` @@ -65,11 +65,11 @@ LL | let _ = match true { - | ---------- `match` arms have incompatible types + | ---------- `match` arms have incompatible types LL | true => ( - | _________________- + | _________________- LL | | @@ -81,11 +81,11 @@ LL | | ), - | |_________- this is found to be of type `{integer}` + | |_________- this is found to be of type `{integer}` LL | false => " - | __________________^ + | __________________^ LL | | @@ -99,7 +99,7 @@ LL | | ", - | |_________^ expected integer, found `&str` + | |_________^ expected integer, found `&str` diff --git a/tests/ui/error-emitter/highlighting.svg b/tests/ui/error-emitter/highlighting.svg index 1d82a97888ae..be92c00c19bd 100644 --- a/tests/ui/error-emitter/highlighting.svg +++ b/tests/ui/error-emitter/highlighting.svg @@ -29,11 +29,11 @@ LL | query(wrapped_fn); - | ----- ^^^^^^^^^^ one type is more general than the other + | ----- ^^^^^^^^^^ one type is more general than the other - | | + | | - | arguments to this function are incorrect + | arguments to this function are incorrect | @@ -49,13 +49,13 @@ LL | fn query(_: fn(Box<(dyn Any + Send + '_)>) -> Pin<Box<( - | ____^^^^^_- + | ____^^^^^_- LL | | dyn Future<Output = Result<Box<(dyn Any + 'static)>, String>> + Send + 'static LL | | )>>) {} - | |___- + | |___- diff --git a/tests/ui/error-emitter/highlighting.windows.svg b/tests/ui/error-emitter/highlighting.windows.svg index 88143f725a5b..152245da9ddc 100644 --- a/tests/ui/error-emitter/highlighting.windows.svg +++ b/tests/ui/error-emitter/highlighting.windows.svg @@ -30,11 +30,11 @@ LL | query(wrapped_fn); - | ----- ^^^^^^^^^^ one type is more general than the other + | ----- ^^^^^^^^^^ one type is more general than the other - | | + | | - | arguments to this function are incorrect + | arguments to this function are incorrect | @@ -50,13 +50,13 @@ LL | fn query(_: fn(Box<(dyn Any + Send + '_)>) -> Pin<Box<( - | ____^^^^^_- + | ____^^^^^_- LL | | dyn Future<Output = Result<Box<(dyn Any + 'static)>, String>> + Send + 'static LL | | )>>) {} - | |___- + | |___- diff --git a/tests/ui/error-emitter/multiline-multipart-suggestion.svg b/tests/ui/error-emitter/multiline-multipart-suggestion.svg index 26210fade74c..c0fb98555ad8 100644 --- a/tests/ui/error-emitter/multiline-multipart-suggestion.svg +++ b/tests/ui/error-emitter/multiline-multipart-suggestion.svg @@ -29,7 +29,7 @@ LL | fn short(foo_bar: &Vec<&i32>) -> &i32 { - | ---------- ^ expected named lifetime parameter + | ---------- ^ expected named lifetime parameter | @@ -53,13 +53,13 @@ LL | foo_bar: &Vec<&i32>, - | ---------- + | ---------- LL | something_very_long_so_that_the_line_will_wrap_around__________: i32, LL | ) -> &i32 { - | ^ expected named lifetime parameter + | ^ expected named lifetime parameter | @@ -73,7 +73,7 @@ LL ~ foo_bar: &'a Vec<&'a i32>, - LL | something_very_long_so_that_the_line_will_wrap_around__________: i32, + LL | something_very_long_so_that_the_line_will_wrap_around__________: i32, LL ~ ) -> &'a i32 { @@ -89,7 +89,7 @@ LL | foo_bar: &Vec<&i32>) -> &i32 { - | ---------- ^ expected named lifetime parameter + | ---------- ^ expected named lifetime parameter | diff --git a/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg b/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg index 3fa9cc18f0de..61b544001f08 100644 --- a/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg +++ b/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg @@ -29,7 +29,7 @@ LL | fn short(foo_bar: &Vec<&i32>) -> &i32 { - | ---------- ^ expected named lifetime parameter + | ---------- ^ expected named lifetime parameter | @@ -53,13 +53,13 @@ LL | foo_bar: &Vec<&i32>, - | ---------- + | ---------- LL | something_very_long_so_that_the_line_will_wrap_around__________: i32, LL | ) -> &i32 { - | ^ expected named lifetime parameter + | ^ expected named lifetime parameter | @@ -73,7 +73,7 @@ LL ~ foo_bar: &'a Vec<&'a i32>, - LL | something_very_long_so_that_the_line_will_wrap_around__________: i32, + LL | something_very_long_so_that_the_line_will_wrap_around__________: i32, LL ~ ) -> &'a i32 { @@ -89,7 +89,7 @@ LL | foo_bar: &Vec<&i32>) -> &i32 { - | ---------- ^ expected named lifetime parameter + | ---------- ^ expected named lifetime parameter | diff --git a/tests/ui/imports/issue-59764.stderr b/tests/ui/imports/issue-59764.stderr index fe58eb97b8db..293c2a60d803 100644 --- a/tests/ui/imports/issue-59764.stderr +++ b/tests/ui/imports/issue-59764.stderr @@ -208,9 +208,9 @@ LL | makro as foobar} help: a macro with this name exists at the root of the crate | LL ~ issue_59764::{makro as foobar, -LL | +LL | ... -LL | +LL | LL ~ foo::{baz} | diff --git a/tests/ui/issues/issue-22644.stderr b/tests/ui/issues/issue-22644.stderr index 0799e9ef11b1..7d8a0ff170a5 100644 --- a/tests/ui/issues/issue-22644.stderr +++ b/tests/ui/issues/issue-22644.stderr @@ -63,9 +63,9 @@ LL | 5); help: try comparing the cast value | LL ~ println!("{}", (a -LL | +LL | ... -LL | +LL | LL ~ usize) | diff --git a/tests/ui/lint/use_suggestion_json.stderr b/tests/ui/lint/use_suggestion_json.stderr index 16fb1682d4a6..acc36550642d 100644 --- a/tests/ui/lint/use_suggestion_json.stderr +++ b/tests/ui/lint/use_suggestion_json.stderr @@ -384,7 +384,7 @@ mod foo { \u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0m$DIR/use_suggestion_json.rs:12:12\u001b[0m \u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m \u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m let x: Iter;\u001b[0m -\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9m^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9mnot found in this scope\u001b[0m +\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9m^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9mnot found in this scope\u001b[0m \u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m \u001b[0m\u001b[1m\u001b[38;5;14mhelp\u001b[0m\u001b[0m: consider importing one of these items\u001b[0m \u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m diff --git a/tests/ui/macros/issue-118048.stderr b/tests/ui/macros/issue-118048.stderr index 6acf78f63b2b..4dc5ef71fec6 100644 --- a/tests/ui/macros/issue-118048.stderr +++ b/tests/ui/macros/issue-118048.stderr @@ -12,7 +12,7 @@ help: use type parameters instead LL ~ fn foo(_: $ty, _: $ty) {} LL | } LL | } -LL | +LL | LL ~ foo!(T); | diff --git a/tests/ui/methods/method-call-err-msg.stderr b/tests/ui/methods/method-call-err-msg.stderr index 7d9b38fb29b5..5a76449e9f95 100644 --- a/tests/ui/methods/method-call-err-msg.stderr +++ b/tests/ui/methods/method-call-err-msg.stderr @@ -55,7 +55,7 @@ LL | / y.zero() LL | | .take() | | -^^^^ `Foo` is not an iterator | |______| - | + | | = note: the following trait bounds were not satisfied: `Foo: Iterator` diff --git a/tests/ui/str/str-escape.stderr b/tests/ui/str/str-escape.stderr index 00fe5444e1a4..c4aee2a110a5 100644 --- a/tests/ui/str/str-escape.stderr +++ b/tests/ui/str/str-escape.stderr @@ -15,7 +15,7 @@ LL | let s = c"foo\ LL | |   bar | | ^ whitespace symbol '\u{a0}' is not skipped | |___| - | + | warning: whitespace symbol '\u{c}' is not skipped --> $DIR/str-escape.rs:26:16 @@ -25,7 +25,7 @@ LL | let s = b"a\ LL | | b"; | | ^- whitespace symbol '\u{c}' is not skipped | |____| - | + | warning: 3 warnings emitted diff --git a/tests/ui/structs-enums/struct-rec/issue-17431-2.stderr b/tests/ui/structs-enums/struct-rec/issue-17431-2.stderr index cdf51632acd0..e818409366d6 100644 --- a/tests/ui/structs-enums/struct-rec/issue-17431-2.stderr +++ b/tests/ui/structs-enums/struct-rec/issue-17431-2.stderr @@ -11,7 +11,7 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle | LL ~ struct Baz { q: Option> } LL | -LL | +LL | LL ~ struct Foo { q: Option> } | diff --git a/tests/ui/structs-enums/struct-rec/mutual-struct-recursion.stderr b/tests/ui/structs-enums/struct-rec/mutual-struct-recursion.stderr index 881bc2819369..afe523939acd 100644 --- a/tests/ui/structs-enums/struct-rec/mutual-struct-recursion.stderr +++ b/tests/ui/structs-enums/struct-rec/mutual-struct-recursion.stderr @@ -16,7 +16,7 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle | LL ~ y: Box>, LL | } -LL | +LL | LL | struct B { LL ~ z: Box> | @@ -39,7 +39,7 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle | LL ~ y: Option>>>, LL | } -LL | +LL | LL | struct D { LL ~ z: Option>>>, | diff --git a/tests/ui/suggestions/issue-99240-2.stderr b/tests/ui/suggestions/issue-99240-2.stderr index 00bffee65293..5b86bc9880f6 100644 --- a/tests/ui/suggestions/issue-99240-2.stderr +++ b/tests/ui/suggestions/issue-99240-2.stderr @@ -8,7 +8,7 @@ LL | // Alias:: LL | || Unit(); | ||________^_- call expression requires function | |________| - | + | | help: `Alias::Unit` is a unit enum variant, and does not take parentheses to be constructed | diff --git a/tests/ui/typeck/issue-100285.stderr b/tests/ui/typeck/issue-100285.stderr index 9c8685a77127..c0deb63af59a 100644 --- a/tests/ui/typeck/issue-100285.stderr +++ b/tests/ui/typeck/issue-100285.stderr @@ -49,7 +49,7 @@ LL ~ return Some(4); LL | } else { LL ~ return Some(5); LL | } -LL | +LL | LL ~ } LL ~ None | diff --git a/tests/ui/typeck/issue-31173.stderr b/tests/ui/typeck/issue-31173.stderr index 0983147a5f0c..9598bc61352f 100644 --- a/tests/ui/typeck/issue-31173.stderr +++ b/tests/ui/typeck/issue-31173.stderr @@ -34,7 +34,7 @@ LL | | .cloned() LL | | .collect(); | | -^^^^^^^ method cannot be called due to unsatisfied trait bounds | |_________| - | + | | = note: the following trait bounds were not satisfied: `, {closure@$DIR/issue-31173.rs:7:21: 7:25}> as Iterator>::Item = &_` diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr index b7e9e1baa7bb..c0fce5c2aaad 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr +++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr @@ -15,7 +15,7 @@ help: consider introducing a named lifetime parameter LL ~ fn main<'a>() { LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=&'a isize>, ... -LL | +LL | LL ~ let _: dyn Foo(&'a isize, &'a usize) -> &'a usize; | diff --git a/tests/ui/variance/variance-regions-unused-indirect.stderr b/tests/ui/variance/variance-regions-unused-indirect.stderr index ec4d480baab7..8cdbb3c0f5eb 100644 --- a/tests/ui/variance/variance-regions-unused-indirect.stderr +++ b/tests/ui/variance/variance-regions-unused-indirect.stderr @@ -16,7 +16,7 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle | LL ~ Foo1(Box>) LL | } -LL | +LL | LL | enum Bar<'a> { LL ~ Bar1(Box>) | From ce48c60c99c33f6df9d2fe6c9e943da4be68f370 Mon Sep 17 00:00:00 2001 From: klensy Date: Fri, 26 Apr 2024 13:47:14 +0300 Subject: [PATCH 087/279] clippy: bless tests --- src/tools/clippy/tests/ui/from_over_into.stderr | 2 +- src/tools/clippy/tests/ui/let_and_return.stderr | 2 +- src/tools/clippy/tests/ui/manual_strip.stderr | 4 ++-- src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr | 2 +- src/tools/clippy/tests/ui/suspicious_doc_comments.stderr | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/clippy/tests/ui/from_over_into.stderr b/src/tools/clippy/tests/ui/from_over_into.stderr index 0649a6cb0f3e..f913ae0bb506 100644 --- a/src/tools/clippy/tests/ui/from_over_into.stderr +++ b/src/tools/clippy/tests/ui/from_over_into.stderr @@ -54,7 +54,7 @@ help: replace the `Into` implementation with `From` LL ~ impl core::convert::From for bool { LL ~ fn from(mut val: crate::ExplicitPaths) -> Self { LL ~ let in_closure = || val.0; -LL | +LL | LL ~ val.0 = false; LL ~ val.0 | diff --git a/src/tools/clippy/tests/ui/let_and_return.stderr b/src/tools/clippy/tests/ui/let_and_return.stderr index f614a5739a86..ff5962ec196e 100644 --- a/src/tools/clippy/tests/ui/let_and_return.stderr +++ b/src/tools/clippy/tests/ui/let_and_return.stderr @@ -71,7 +71,7 @@ LL | result help: return the expression directly | LL ~ -LL | +LL | LL ~ (match self { LL + E::A(x) => x, LL + E::B(x) => x, diff --git a/src/tools/clippy/tests/ui/manual_strip.stderr b/src/tools/clippy/tests/ui/manual_strip.stderr index d2d4f765310b..a70c988a0549 100644 --- a/src/tools/clippy/tests/ui/manual_strip.stderr +++ b/src/tools/clippy/tests/ui/manual_strip.stderr @@ -17,7 +17,7 @@ LL ~ if let Some() = s.strip_prefix("ab") { LL ~ str::to_string(); LL | LL ~ .to_string(); -LL | +LL | LL ~ str::to_string(); LL ~ .to_string(); | @@ -39,7 +39,7 @@ LL ~ if let Some() = s.strip_suffix("bc") { LL ~ str::to_string(); LL | LL ~ .to_string(); -LL | +LL | LL ~ str::to_string(); LL ~ .to_string(); | diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr index fa2ac7a1b37e..d69c86c70e29 100644 --- a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr +++ b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr @@ -27,7 +27,7 @@ LL | || do_nothing(value) LL | || }); | ||______^- help: try: `if let Ok(value) = x.field { ... }` | |______| - | + | error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> tests/ui/result_map_unit_fn_unfixable.rs:37:5 diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr b/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr index b54309b44d5d..f12053b1595a 100644 --- a/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr +++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr @@ -85,7 +85,7 @@ LL | | ///! b help: use an inner doc comment to document the parent module or crate | LL ~ //! a -LL | +LL | LL ~ //! b | From a8e0bcb3365670a376ca6606b48c26e3d3a3a65d Mon Sep 17 00:00:00 2001 From: klensy Date: Fri, 26 Apr 2024 13:47:14 +0300 Subject: [PATCH 088/279] clippy: bless tests --- tests/ui/from_over_into.stderr | 2 +- tests/ui/let_and_return.stderr | 2 +- tests/ui/manual_strip.stderr | 4 ++-- tests/ui/result_map_unit_fn_unfixable.stderr | 2 +- tests/ui/suspicious_doc_comments.stderr | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/ui/from_over_into.stderr b/tests/ui/from_over_into.stderr index 0649a6cb0f3e..f913ae0bb506 100644 --- a/tests/ui/from_over_into.stderr +++ b/tests/ui/from_over_into.stderr @@ -54,7 +54,7 @@ help: replace the `Into` implementation with `From` LL ~ impl core::convert::From for bool { LL ~ fn from(mut val: crate::ExplicitPaths) -> Self { LL ~ let in_closure = || val.0; -LL | +LL | LL ~ val.0 = false; LL ~ val.0 | diff --git a/tests/ui/let_and_return.stderr b/tests/ui/let_and_return.stderr index f614a5739a86..ff5962ec196e 100644 --- a/tests/ui/let_and_return.stderr +++ b/tests/ui/let_and_return.stderr @@ -71,7 +71,7 @@ LL | result help: return the expression directly | LL ~ -LL | +LL | LL ~ (match self { LL + E::A(x) => x, LL + E::B(x) => x, diff --git a/tests/ui/manual_strip.stderr b/tests/ui/manual_strip.stderr index d2d4f765310b..a70c988a0549 100644 --- a/tests/ui/manual_strip.stderr +++ b/tests/ui/manual_strip.stderr @@ -17,7 +17,7 @@ LL ~ if let Some() = s.strip_prefix("ab") { LL ~ str::to_string(); LL | LL ~ .to_string(); -LL | +LL | LL ~ str::to_string(); LL ~ .to_string(); | @@ -39,7 +39,7 @@ LL ~ if let Some() = s.strip_suffix("bc") { LL ~ str::to_string(); LL | LL ~ .to_string(); -LL | +LL | LL ~ str::to_string(); LL ~ .to_string(); | diff --git a/tests/ui/result_map_unit_fn_unfixable.stderr b/tests/ui/result_map_unit_fn_unfixable.stderr index fa2ac7a1b37e..d69c86c70e29 100644 --- a/tests/ui/result_map_unit_fn_unfixable.stderr +++ b/tests/ui/result_map_unit_fn_unfixable.stderr @@ -27,7 +27,7 @@ LL | || do_nothing(value) LL | || }); | ||______^- help: try: `if let Ok(value) = x.field { ... }` | |______| - | + | error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()` --> tests/ui/result_map_unit_fn_unfixable.rs:37:5 diff --git a/tests/ui/suspicious_doc_comments.stderr b/tests/ui/suspicious_doc_comments.stderr index b54309b44d5d..f12053b1595a 100644 --- a/tests/ui/suspicious_doc_comments.stderr +++ b/tests/ui/suspicious_doc_comments.stderr @@ -85,7 +85,7 @@ LL | | ///! b help: use an inner doc comment to document the parent module or crate | LL ~ //! a -LL | +LL | LL ~ //! b | From 255a1e9554286007ea5556f7123ceeeb3f9f6db1 Mon Sep 17 00:00:00 2001 From: Daria Sukhonina Date: Sat, 27 Apr 2024 11:59:50 +0300 Subject: [PATCH 089/279] Relax `A: Clone` bound for `rc::Weak::into_raw_and_alloc` --- library/alloc/src/rc.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index a320a244abd7..c245b42c3e88 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -3029,13 +3029,10 @@ impl Weak { /// [`as_ptr`]: Weak::as_ptr #[inline] #[unstable(feature = "allocator_api", issue = "32838")] - pub fn into_raw_and_alloc(self) -> (*const T, A) - where - A: Clone, - { - let result = self.as_ptr(); - let alloc = self.alloc.clone(); - mem::forget(self); + pub fn into_raw_and_alloc(self) -> (*const T, A) { + let rc = mem::ManuallyDrop::new(self); + let result = rc.as_ptr(); + let alloc = unsafe { ptr::read(&rc.alloc) }; (result, alloc) } From 163ea3328b771a7092c1345de6a1122158651655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 27 Apr 2024 11:36:42 +0200 Subject: [PATCH 090/279] Move `TOOLSTATE_REPO` to top-level env --- .github/workflows/ci.yml | 3 ++- src/ci/github-actions/ci.yml | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 231bb971713f..3a607defdb2c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,6 +34,8 @@ defaults: concurrency: group: "${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }}" cancel-in-progress: true +env: + TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate" jobs: calculate_matrix: name: Calculate job matrix @@ -61,7 +63,6 @@ jobs: HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}" DOCKER_TOKEN: "${{ secrets.GITHUB_TOKEN }}" SCCACHE_BUCKET: rust-lang-ci-sccache2 - TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate" CACHE_DOMAIN: ci-caches.rust-lang.org continue-on-error: "${{ matrix.continue_on_error || false }}" strategy: diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 98b27950fbb0..a96170089f0c 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -84,6 +84,9 @@ concurrency: group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }} cancel-in-progress: true +env: + TOOLSTATE_REPO: https://github.com/rust-lang-nursery/rust-toolstate + jobs: # The job matrix for `calculate_matrix` is defined in src/ci/github-actions/jobs.yml. # It calculates which jobs should be executed, based on the data of the ${{ github }} context. @@ -114,7 +117,6 @@ jobs: HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} DOCKER_TOKEN: ${{ secrets.GITHUB_TOKEN }} SCCACHE_BUCKET: rust-lang-ci-sccache2 - TOOLSTATE_REPO: https://github.com/rust-lang-nursery/rust-toolstate CACHE_DOMAIN: ci-caches.rust-lang.org continue-on-error: ${{ matrix.continue_on_error || false }} strategy: From 31af4f81ca68dfa8dac34373842b64b41f4e0abf Mon Sep 17 00:00:00 2001 From: George Bateman Date: Sat, 27 Apr 2024 12:38:51 +0100 Subject: [PATCH 091/279] Remove lazycell and once_cell from compiletest dependencies --- Cargo.lock | 8 -- src/tools/compiletest/Cargo.toml | 2 - src/tools/compiletest/src/common.rs | 12 +-- src/tools/compiletest/src/errors.rs | 9 +- src/tools/compiletest/src/header.rs | 9 +- src/tools/compiletest/src/lib.rs | 5 +- src/tools/compiletest/src/runtest.rs | 147 ++++++++++++--------------- 7 files changed, 80 insertions(+), 112 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b2593ebbb12..ac6e7974a127 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -760,11 +760,9 @@ dependencies = [ "glob", "home", "indexmap", - "lazycell", "libc", "miow", "miropt-test-tools", - "once_cell", "regex", "rustfix 0.8.1", "serde", @@ -2151,12 +2149,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "leb128" version = "0.2.5" diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index 38c29b91928c..52beb4c8b3de 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -21,10 +21,8 @@ regex = "1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" rustfix = "0.8.1" -once_cell = "1.16.0" walkdir = "2" glob = "0.3.0" -lazycell = "1.3.0" anyhow = "1" home = "0.5.5" diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index aa69791b3b4b..afbcc3e92bcb 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -6,10 +6,10 @@ use std::iter; use std::path::{Path, PathBuf}; use std::process::Command; use std::str::FromStr; +use std::sync::OnceLock; use crate::util::{add_dylib_path, PathBufExt}; use build_helper::git::GitConfig; -use lazycell::AtomicLazyCell; use serde::de::{Deserialize, Deserializer, Error as _}; use std::collections::{HashMap, HashSet}; use test::{ColorConfig, OutputFormat}; @@ -384,7 +384,7 @@ pub struct Config { /// Only rerun the tests that result has been modified accoring to Git status pub only_modified: bool, - pub target_cfgs: AtomicLazyCell, + pub target_cfgs: OnceLock, pub nocapture: bool, @@ -406,13 +406,7 @@ impl Config { } pub fn target_cfgs(&self) -> &TargetCfgs { - match self.target_cfgs.borrow() { - Some(cfgs) => cfgs, - None => { - let _ = self.target_cfgs.fill(TargetCfgs::new(self)); - self.target_cfgs.borrow().unwrap() - } - } + self.target_cfgs.get_or_init(|| TargetCfgs::new(self)) } pub fn target_cfg(&self) -> &TargetCfg { diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs index 3231f9fd3a4b..c11d3da13a8b 100644 --- a/src/tools/compiletest/src/errors.rs +++ b/src/tools/compiletest/src/errors.rs @@ -6,8 +6,8 @@ use std::io::prelude::*; use std::io::BufReader; use std::path::Path; use std::str::FromStr; +use std::sync::OnceLock; -use once_cell::sync::Lazy; use regex::Regex; use tracing::*; @@ -117,10 +117,11 @@ fn parse_expected( // //~^^^^^ // //[rev1]~ // //[rev1,rev2]~^^ - static RE: Lazy = - Lazy::new(|| Regex::new(r"//(?:\[(?P[\w\-,]+)])?~(?P\||\^*)").unwrap()); + static RE: OnceLock = OnceLock::new(); - let captures = RE.captures(line)?; + let captures = RE + .get_or_init(|| Regex::new(r"//(?:\[(?P[\w\-,]+)])?~(?P\||\^*)").unwrap()) + .captures(line)?; match (test_revision, captures.name("revs")) { // Only error messages that contain our revision between the square brackets apply to us. diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 8aafbb3e3992..34e65c7d61fe 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -5,8 +5,8 @@ use std::io::prelude::*; use std::io::BufReader; use std::path::{Path, PathBuf}; use std::process::Command; +use std::sync::OnceLock; -use once_cell::sync::Lazy; use regex::Regex; use tracing::*; @@ -1021,8 +1021,9 @@ fn iter_header( let mut line_number = 0; // Match on error annotations like `//~ERROR`. - static REVISION_MAGIC_COMMENT_RE: Lazy = - Lazy::new(|| Regex::new("//(\\[.*\\])?~.*").unwrap()); + static REVISION_MAGIC_COMMENT_RE: OnceLock = OnceLock::new(); + let revision_magic_comment_re = + REVISION_MAGIC_COMMENT_RE.get_or_init(|| Regex::new("//(\\[.*\\])?~.*").unwrap()); loop { line_number += 1; @@ -1087,7 +1088,7 @@ fn iter_header( }); // Then we try to check for legacy-style candidates, which are not the magic ~ERROR family // error annotations. - } else if !REVISION_MAGIC_COMMENT_RE.is_match(ln) { + } else if !revision_magic_comment_re.is_match(ln) { let Some((_, rest)) = line_directive("//", ln) else { continue; }; diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index c8a8b79921e2..2e45caec46cd 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -24,13 +24,13 @@ use crate::util::logv; use build_helper::git::{get_git_modified_files, get_git_untracked_files}; use core::panic; use getopts::Options; -use lazycell::AtomicLazyCell; use std::collections::HashSet; use std::ffi::OsString; use std::fs; use std::io::{self, ErrorKind}; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; +use std::sync::{Arc, OnceLock}; use std::time::SystemTime; use std::{env, vec}; use test::ColorConfig; @@ -39,7 +39,6 @@ use walkdir::WalkDir; use self::header::{make_test_description, EarlyProps}; use crate::header::HeadersCache; -use std::sync::Arc; pub fn parse_config(args: Vec) -> Config { let mut opts = Options::new(); @@ -320,7 +319,7 @@ pub fn parse_config(args: Vec) -> Config { force_rerun: matches.opt_present("force-rerun"), - target_cfgs: AtomicLazyCell::new(), + target_cfgs: OnceLock::new(), nocapture: matches.opt_present("nocapture"), diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 1dd639a89188..b0f84b1162f4 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -36,7 +36,6 @@ use std::sync::Arc; use anyhow::Context; use glob::glob; -use once_cell::sync::Lazy; use tracing::*; use crate::extract_gdb_version; @@ -48,6 +47,13 @@ use debugger::DebuggerCommands; #[cfg(test)] mod tests; +macro_rules! static_regex { + ($re:literal) => {{ + static RE: ::std::sync::OnceLock<::regex::Regex> = ::std::sync::OnceLock::new(); + RE.get_or_init(|| ::regex::Regex::new($re).unwrap()) + }}; +} + const FAKE_SRC_BASE: &str = "fake-test-src-base"; #[cfg(windows)] @@ -765,28 +771,23 @@ impl<'test> TestCx<'test> { // ` 100|` => ` LL|` // ` | 1000|` => ` | LL|` // ` | | 1000|` => ` | | LL|` - static LINE_NUMBER_RE: Lazy = - Lazy::new(|| Regex::new(r"(?m:^)(?(?: \|)*) *[0-9]+\|").unwrap()); - let coverage = LINE_NUMBER_RE.replace_all(&coverage, "${prefix} LL|"); + let coverage = static_regex!(r"(?m:^)(?(?: \|)*) *[0-9]+\|") + .replace_all(&coverage, "${prefix} LL|"); // ` | Branch (1:` => ` | Branch (LL:` // ` | | Branch (10:` => ` | | Branch (LL:` - static BRANCH_LINE_NUMBER_RE: Lazy = - Lazy::new(|| Regex::new(r"(?m:^)(?(?: \|)+ Branch \()[0-9]+:").unwrap()); - let coverage = BRANCH_LINE_NUMBER_RE.replace_all(&coverage, "${prefix}LL:"); + let coverage = static_regex!(r"(?m:^)(?(?: \|)+ Branch \()[0-9]+:") + .replace_all(&coverage, "${prefix}LL:"); // ` |---> MC/DC Decision Region (1:30) to (2:` => ` |---> MC/DC Decision Region (LL:30) to (LL:` - static MCDC_DECISION_LINE_NUMBER_RE: Lazy = Lazy::new(|| { - Regex::new(r"(?m:^)(?(?: \|)+---> MC/DC Decision Region \()[0-9]+:(?[0-9]+\) to \()[0-9]+:").unwrap() - }); let coverage = - MCDC_DECISION_LINE_NUMBER_RE.replace_all(&coverage, "${prefix}LL:${middle}LL:"); + static_regex!(r"(?m:^)(?(?: \|)+---> MC/DC Decision Region \()[0-9]+:(?[0-9]+\) to \()[0-9]+:") + .replace_all(&coverage, "${prefix}LL:${middle}LL:"); // ` | Condition C1 --> (1:` => ` | Condition C1 --> (LL:` - static MCDC_CONDITION_LINE_NUMBER_RE: Lazy = Lazy::new(|| { - Regex::new(r"(?m:^)(?(?: \|)+ Condition C[0-9]+ --> \()[0-9]+:").unwrap() - }); - let coverage = MCDC_CONDITION_LINE_NUMBER_RE.replace_all(&coverage, "${prefix}LL:"); + let coverage = + static_regex!(r"(?m:^)(?(?: \|)+ Condition C[0-9]+ --> \()[0-9]+:") + .replace_all(&coverage, "${prefix}LL:"); coverage.into_owned() } @@ -3471,13 +3472,12 @@ impl<'test> TestCx<'test> { // the form .-in-., // remove all crate-disambiguators. fn remove_crate_disambiguator_from_cgu(cgu: &str) -> String { - static RE: Lazy = Lazy::new(|| { - Regex::new(r"^[^\.]+(?P\.[[:alnum:]]+)(-in-[^\.]+(?P\.[[:alnum:]]+))?") - .unwrap() - }); - - let captures = - RE.captures(cgu).unwrap_or_else(|| panic!("invalid cgu name encountered: {}", cgu)); + let Some(captures) = + static_regex!(r"^[^\.]+(?P\.[[:alnum:]]+)(-in-[^\.]+(?P\.[[:alnum:]]+))?") + .captures(cgu) + else { + panic!("invalid cgu name encountered: {cgu}"); + }; let mut new_name = cgu.to_owned(); @@ -4073,18 +4073,16 @@ impl<'test> TestCx<'test> { // 'uploaded "$TEST_BUILD_DIR/, waiting for result"' // is printed to stdout by the client and then captured in the ProcRes, // so it needs to be removed when comparing the run-pass test execution output. - static REMOTE_TEST_RE: Lazy = Lazy::new(|| { - Regex::new( - "^uploaded \"\\$TEST_BUILD_DIR(/[[:alnum:]_\\-.]+)+\", waiting for result\n" - ) - .unwrap() - }); - normalized_stdout = REMOTE_TEST_RE.replace(&normalized_stdout, "").to_string(); + normalized_stdout = static_regex!( + "^uploaded \"\\$TEST_BUILD_DIR(/[[:alnum:]_\\-.]+)+\", waiting for result\n" + ) + .replace(&normalized_stdout, "") + .to_string(); // When there is a panic, the remote-test-client also prints "died due to signal"; // that needs to be removed as well. - static SIGNAL_DIED_RE: Lazy = - Lazy::new(|| Regex::new("^died due to signal [0-9]+\n").unwrap()); - normalized_stdout = SIGNAL_DIED_RE.replace(&normalized_stdout, "").to_string(); + normalized_stdout = static_regex!("^died due to signal [0-9]+\n") + .replace(&normalized_stdout, "") + .to_string(); // FIXME: it would be much nicer if we could just tell the remote-test-client to not // print these things. } @@ -4556,10 +4554,9 @@ impl<'test> TestCx<'test> { // with placeholders as we do not want tests needing updated when compiler source code // changes. // eg. $SRC_DIR/libcore/mem.rs:323:14 becomes $SRC_DIR/libcore/mem.rs:LL:COL - static SRC_DIR_RE: Lazy = - Lazy::new(|| Regex::new("SRC_DIR(.+):\\d+:\\d+(: \\d+:\\d+)?").unwrap()); - - normalized = SRC_DIR_RE.replace_all(&normalized, "SRC_DIR$1:LL:COL").into_owned(); + normalized = static_regex!("SRC_DIR(.+):\\d+:\\d+(: \\d+:\\d+)?") + .replace_all(&normalized, "SRC_DIR$1:LL:COL") + .into_owned(); normalized = Self::normalize_platform_differences(&normalized); normalized = normalized.replace("\t", "\\t"); // makes tabs visible @@ -4568,34 +4565,29 @@ impl<'test> TestCx<'test> { // since they duplicate actual errors and make the output hard to read. // This mirrors the regex in src/tools/tidy/src/style.rs, please update // both if either are changed. - static ANNOTATION_RE: Lazy = - Lazy::new(|| Regex::new("\\s*//(\\[.*\\])?~.*").unwrap()); - - normalized = ANNOTATION_RE.replace_all(&normalized, "").into_owned(); + normalized = + static_regex!("\\s*//(\\[.*\\])?~.*").replace_all(&normalized, "").into_owned(); // This code normalizes various hashes in v0 symbol mangling that is // emitted in the ui and mir-opt tests. - static V0_CRATE_HASH_PREFIX_RE: Lazy = - Lazy::new(|| Regex::new(r"_R.*?Cs[0-9a-zA-Z]+_").unwrap()); - static V0_CRATE_HASH_RE: Lazy = - Lazy::new(|| Regex::new(r"Cs[0-9a-zA-Z]+_").unwrap()); + let v0_crate_hash_prefix_re = static_regex!(r"_R.*?Cs[0-9a-zA-Z]+_"); + let v0_crate_hash_re = static_regex!(r"Cs[0-9a-zA-Z]+_"); const V0_CRATE_HASH_PLACEHOLDER: &str = r"CsCRATE_HASH_"; - if V0_CRATE_HASH_PREFIX_RE.is_match(&normalized) { + if v0_crate_hash_prefix_re.is_match(&normalized) { // Normalize crate hash normalized = - V0_CRATE_HASH_RE.replace_all(&normalized, V0_CRATE_HASH_PLACEHOLDER).into_owned(); + v0_crate_hash_re.replace_all(&normalized, V0_CRATE_HASH_PLACEHOLDER).into_owned(); } - static V0_BACK_REF_PREFIX_RE: Lazy = - Lazy::new(|| Regex::new(r"\(_R.*?B[0-9a-zA-Z]_").unwrap()); - static V0_BACK_REF_RE: Lazy = Lazy::new(|| Regex::new(r"B[0-9a-zA-Z]_").unwrap()); + let v0_back_ref_prefix_re = static_regex!(r"\(_R.*?B[0-9a-zA-Z]_"); + let v0_back_ref_re = static_regex!(r"B[0-9a-zA-Z]_"); const V0_BACK_REF_PLACEHOLDER: &str = r"B_"; - if V0_BACK_REF_PREFIX_RE.is_match(&normalized) { + if v0_back_ref_prefix_re.is_match(&normalized) { // Normalize back references (see RFC 2603) normalized = - V0_BACK_REF_RE.replace_all(&normalized, V0_BACK_REF_PLACEHOLDER).into_owned(); + v0_back_ref_re.replace_all(&normalized, V0_BACK_REF_PLACEHOLDER).into_owned(); } // AllocId are numbered globally in a compilation session. This can lead to changes @@ -4608,26 +4600,22 @@ impl<'test> TestCx<'test> { let mut seen_allocs = indexmap::IndexSet::new(); // The alloc-id appears in pretty-printed allocations. - static ALLOC_ID_PP_RE: Lazy = Lazy::new(|| { - Regex::new(r"╾─*a(lloc)?([0-9]+)(\+0x[0-9]+)?()?( \([0-9]+ ptr bytes\))?─*╼") - .unwrap() - }); - normalized = ALLOC_ID_PP_RE - .replace_all(&normalized, |caps: &Captures<'_>| { - // Renumber the captured index. - let index = caps.get(2).unwrap().as_str().to_string(); - let (index, _) = seen_allocs.insert_full(index); - let offset = caps.get(3).map_or("", |c| c.as_str()); - let imm = caps.get(4).map_or("", |c| c.as_str()); - // Do not bother keeping it pretty, just make it deterministic. - format!("╾ALLOC{index}{offset}{imm}╼") - }) - .into_owned(); + normalized = static_regex!( + r"╾─*a(lloc)?([0-9]+)(\+0x[0-9]+)?()?( \([0-9]+ ptr bytes\))?─*╼" + ) + .replace_all(&normalized, |caps: &Captures<'_>| { + // Renumber the captured index. + let index = caps.get(2).unwrap().as_str().to_string(); + let (index, _) = seen_allocs.insert_full(index); + let offset = caps.get(3).map_or("", |c| c.as_str()); + let imm = caps.get(4).map_or("", |c| c.as_str()); + // Do not bother keeping it pretty, just make it deterministic. + format!("╾ALLOC{index}{offset}{imm}╼") + }) + .into_owned(); // The alloc-id appears in a sentence. - static ALLOC_ID_RE: Lazy = - Lazy::new(|| Regex::new(r"\balloc([0-9]+)\b").unwrap()); - normalized = ALLOC_ID_RE + normalized = static_regex!(r"\balloc([0-9]+)\b") .replace_all(&normalized, |caps: &Captures<'_>| { let index = caps.get(1).unwrap().as_str().to_string(); let (index, _) = seen_allocs.insert_full(index); @@ -4650,12 +4638,13 @@ impl<'test> TestCx<'test> { /// Replaces backslashes in paths with forward slashes, and replaces CRLF line endings /// with LF. fn normalize_platform_differences(output: &str) -> String { - /// Used to find Windows paths. - /// - /// It's not possible to detect paths in the error messages generally, but this is a - /// decent enough heuristic. - static PATH_BACKSLASH_RE: Lazy = Lazy::new(|| { - Regex::new( + let output = output.replace(r"\\", r"\"); + + // Used to find Windows paths. + // + // It's not possible to detect paths in the error messages generally, but this is a + // decent enough heuristic. + static_regex!( r#"(?x) (?: # Match paths that don't include spaces. @@ -4663,14 +4652,8 @@ impl<'test> TestCx<'test> { | # If the path starts with a well-known root, then allow spaces and no file extension. \$(?:DIR|SRC_DIR|TEST_BUILD_DIR|BUILD_DIR|LIB_DIR)(?:\\[\pL\pN\.\-_'\ ]+)+ - )"#, + )"# ) - .unwrap() - }); - - let output = output.replace(r"\\", r"\"); - - PATH_BACKSLASH_RE .replace_all(&output, |caps: &Captures<'_>| { println!("{}", &caps[0]); caps[0].replace(r"\", "/") From 4faaa5339217267bfb4a0a26303f7197e56dcc72 Mon Sep 17 00:00:00 2001 From: Lin Yihai Date: Sat, 27 Apr 2024 21:22:04 +0800 Subject: [PATCH 092/279] doc: Replace mod.rs with the appropriate link --- compiler/rustc_hir_typeck/src/expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 8923137fdd82..354324b5e972 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1,6 +1,6 @@ //! Type checking expressions. //! -//! See `mod.rs` for more context on type checking in general. +//! See [`rustc_hir_analysis::check`] for more context on type checking in general. use crate::cast; use crate::coercion::CoerceMany; From a700897d5a46c03f9cac060b6854de44ac33733b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 27 Apr 2024 15:48:35 +0200 Subject: [PATCH 093/279] Add missing checkout step --- .github/workflows/ci.yml | 4 ++++ src/ci/github-actions/ci.yml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3a607defdb2c..d691b72488b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -177,6 +177,10 @@ jobs: - job if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" steps: + - name: checkout the source code + uses: actions/checkout@v4 + with: + fetch-depth: 2 - name: publish toolstate run: src/ci/publish_toolstate.sh shell: bash diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index a96170089f0c..95d2225a6b1c 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -286,6 +286,10 @@ jobs: if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" <<: *base-outcome-job steps: + - name: checkout the source code + uses: actions/checkout@v4 + with: + fetch-depth: 2 - name: publish toolstate run: src/ci/publish_toolstate.sh shell: bash From 825a3b1f09c1b2598aa9a0fdabe5ad051e5e1c98 Mon Sep 17 00:00:00 2001 From: JirCep Date: Sat, 27 Apr 2024 16:57:20 +0200 Subject: [PATCH 094/279] String.truncate calls Vec.truncate, in turn, and that states "is greater or equal to". Beside common sense. --- library/alloc/src/string.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 7c9f13e30ffb..414486ed75f3 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1382,7 +1382,7 @@ impl String { /// Shortens this `String` to the specified length. /// - /// If `new_len` is greater than the string's current length, this has no + /// If `new_len` is greater than or equal to the string's current length, this has no /// effect. /// /// Note that this method has no effect on the allocated capacity From f840da757f1e40c18b4627274046197ad46e4f50 Mon Sep 17 00:00:00 2001 From: JirCep Date: Sat, 27 Apr 2024 17:18:25 +0200 Subject: [PATCH 095/279] WS fix. --- library/alloc/src/string.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 414486ed75f3..2a859ad55eed 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1382,7 +1382,7 @@ impl String { /// Shortens this `String` to the specified length. /// - /// If `new_len` is greater than or equal to the string's current length, this has no + /// If `new_len` is greater than or equal to the string's current length, this has no /// effect. /// /// Note that this method has no effect on the allocated capacity From adebad1dce19299c3c4f59d9f93d82af16abdfa9 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Sat, 27 Apr 2024 18:36:29 +0200 Subject: [PATCH 096/279] Elaborate in comment about `statx` probe As requested by @workingjubilee in https://github.com/rust-lang/rust/pull/123928#discussion_r1564916743. --- library/std/src/sys/pal/unix/fs.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 3456155509ef..c37332ac6b10 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -198,20 +198,16 @@ cfg_has_statx! {{ return Some(Err(err)); } - // `ENOSYS` might come from a faulty FUSE driver. - // - // Other errors are not a good enough indicator either -- it is - // known that `EPERM` can be returned as a result of using seccomp to - // block the syscall. + // We're not yet entirely sure whether `statx` is usable on this kernel + // or not. Syscalls can return errors from things other than the kernel + // per se, e.g. `EPERM` can be returned if seccomp is used to block the + // syscall, or `ENOSYS` might be returned from a faulty FUSE driver. // // Availability is checked by performing a call which expects `EFAULT` // if the syscall is usable. // // See: https://github.com/rust-lang/rust/issues/65662 // - // FIXME this can probably just do the call if `EPERM` was received, but - // previous iteration of the code checked it for all errors and for now - // this is retained. // FIXME what about transient conditions like `ENOMEM`? let err2 = cvt(statx(0, ptr::null(), 0, libc::STATX_ALL, ptr::null_mut())) .err() From 4e83776731b1b80f999d89fed4f382641119bbfb Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sat, 27 Apr 2024 08:05:32 +0200 Subject: [PATCH 097/279] bootstrap: Document `struct Builder` and its fields --- src/bootstrap/src/core/builder.rs | 21 +++++++++++++++++++++ src/bootstrap/src/core/config/config.rs | 2 ++ 2 files changed, 23 insertions(+) diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index adef9ebd0e30..dc01f616c2cc 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -34,13 +34,34 @@ use once_cell::sync::Lazy; #[cfg(test)] mod tests; +/// Builds and performs different [`Self::kind`]s of stuff and actions, taking +/// into account build configuration from e.g. config.toml. pub struct Builder<'a> { + /// Build configuration from e.g. config.toml. pub build: &'a Build, + + /// The stage to use. Either implicitly determined based on subcommand, or + /// explicitly specified with `--stage N`. Normally this is the stage we + /// use, but sometimes we want to run steps with a lower stage than this. pub top_stage: u32, + + /// What to build or what action to perform. pub kind: Kind, + + /// A cache of outputs of [`Step`]s so we can avoid running steps we already + /// ran. cache: Cache, + + /// A stack of [`Step`]s to run before we can run this builder. The output + /// of steps is cached in [`Self::cache`]. stack: RefCell>>, + + /// The total amount of time we spent running [`Step`]s in [`Self::stack`]. time_spent_on_dependencies: Cell, + + /// The paths passed on the command line. Used by steps to figure out what + /// to do. For example: with `./x check foo bar` we get `paths=["foo", + /// "bar"]`. pub paths: Vec, } diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 2acce6273598..019413ee5629 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -345,6 +345,8 @@ pub struct Config { #[cfg(test)] pub initial_rustfmt: RefCell, + /// The paths to work with. For example: with `./x check foo bar` we get + /// `paths=["foo", "bar"]`. pub paths: Vec, } From 4c2a7d17cf771cd629ff19fbfd2037ff6ca37e22 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sat, 27 Apr 2024 19:30:21 +0200 Subject: [PATCH 098/279] bootstrap: Change `global(true)` to `global = true` for flags for consistency All other arg properties use the `prop = value` style, which makes it slightly annoying to use the `prop(value)` style for `global`. Change to `prop = value` also for `global` for consistency. --- src/bootstrap/src/core/config/flags.rs | 80 +++++++++++++------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index aaa2a2c47e07..b2124c65c225 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -41,72 +41,72 @@ pub struct Flags { #[command(subcommand)] pub cmd: Subcommand, - #[arg(global(true), short, long, action = clap::ArgAction::Count)] + #[arg(global = true, short, long, action = clap::ArgAction::Count)] /// use verbose output (-vv for very verbose) pub verbose: u8, // each extra -v after the first is passed to Cargo - #[arg(global(true), short, long)] + #[arg(global = true, short, long)] /// use incremental compilation pub incremental: bool, - #[arg(global(true), long, value_hint = clap::ValueHint::FilePath, value_name = "FILE")] + #[arg(global = true, long, value_hint = clap::ValueHint::FilePath, value_name = "FILE")] /// TOML configuration file for build pub config: Option, - #[arg(global(true), long, value_hint = clap::ValueHint::DirPath, value_name = "DIR")] + #[arg(global = true, long, value_hint = clap::ValueHint::DirPath, value_name = "DIR")] /// Build directory, overrides `build.build-dir` in `config.toml` pub build_dir: Option, - #[arg(global(true), long, value_hint = clap::ValueHint::Other, value_name = "BUILD")] + #[arg(global = true, long, value_hint = clap::ValueHint::Other, value_name = "BUILD")] /// build target of the stage0 compiler pub build: Option, - #[arg(global(true), long, value_hint = clap::ValueHint::Other, value_name = "HOST", value_parser = target_selection_list)] + #[arg(global = true, long, value_hint = clap::ValueHint::Other, value_name = "HOST", value_parser = target_selection_list)] /// host targets to build pub host: Option, - #[arg(global(true), long, value_hint = clap::ValueHint::Other, value_name = "TARGET", value_parser = target_selection_list)] + #[arg(global = true, long, value_hint = clap::ValueHint::Other, value_name = "TARGET", value_parser = target_selection_list)] /// target targets to build pub target: Option, - #[arg(global(true), long, value_name = "PATH")] + #[arg(global = true, long, value_name = "PATH")] /// build paths to exclude pub exclude: Vec, // keeping for client backward compatibility - #[arg(global(true), long, value_name = "PATH")] + #[arg(global = true, long, value_name = "PATH")] /// build paths to skip pub skip: Vec, - #[arg(global(true), long)] + #[arg(global = true, long)] /// include default paths in addition to the provided ones pub include_default_paths: bool, - #[arg(global(true), value_hint = clap::ValueHint::Other, long)] + #[arg(global = true, value_hint = clap::ValueHint::Other, long)] pub rustc_error_format: Option, - #[arg(global(true), long, value_hint = clap::ValueHint::CommandString, value_name = "CMD")] + #[arg(global = true, long, value_hint = clap::ValueHint::CommandString, value_name = "CMD")] /// command to run on failure pub on_fail: Option, - #[arg(global(true), long)] + #[arg(global = true, long)] /// dry run; don't build anything pub dry_run: bool, /// Indicates whether to dump the work done from bootstrap shims - #[arg(global(true), long)] + #[arg(global = true, long)] pub dump_bootstrap_shims: bool, - #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "N")] + #[arg(global = true, value_hint = clap::ValueHint::Other, long, value_name = "N")] /// stage to build (indicates compiler to use/test, e.g., stage 0 uses the /// bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.) pub stage: Option, - #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "N")] + #[arg(global = true, value_hint = clap::ValueHint::Other, long, value_name = "N")] /// stage(s) to keep without recompiling /// (pass multiple times to keep e.g., both stages 0 and 1) pub keep_stage: Vec, - #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "N")] + #[arg(global = true, value_hint = clap::ValueHint::Other, long, value_name = "N")] /// stage(s) of the standard library to keep without recompiling /// (pass multiple times to keep e.g., both stages 0 and 1) pub keep_stage_std: Vec, - #[arg(global(true), long, value_hint = clap::ValueHint::DirPath, value_name = "DIR")] + #[arg(global = true, long, value_hint = clap::ValueHint::DirPath, value_name = "DIR")] /// path to the root of the rust checkout pub src: Option, #[arg( - global(true), + global = true, short, long, value_hint = clap::ValueHint::Other, @@ -117,26 +117,26 @@ pub struct Flags { pub jobs: usize, // This overrides the deny-warnings configuration option, // which passes -Dwarnings to the compiler invocations. - #[arg(global(true), long)] + #[arg(global = true, long)] #[arg(value_enum, default_value_t=Warnings::Default, value_name = "deny|warn")] /// if value is deny, will deny warnings /// if value is warn, will emit warnings /// otherwise, use the default configured behaviour pub warnings: Warnings, - #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "FORMAT")] + #[arg(global = true, value_hint = clap::ValueHint::Other, long, value_name = "FORMAT")] /// rustc error format pub error_format: Option, - #[arg(global(true), long)] + #[arg(global = true, long)] /// use message-format=json pub json_output: bool, - #[arg(global(true), long, value_name = "STYLE")] + #[arg(global = true, long, value_name = "STYLE")] #[arg(value_enum, default_value_t = Color::Auto)] /// whether to use color in cargo and rustc output pub color: Color, - #[arg(global(true), long)] + #[arg(global = true, long)] /// Bootstrap uses this value to decide whether it should bypass locking the build process. /// This is rarely needed (e.g., compiling the std library for different targets in parallel). /// @@ -144,41 +144,41 @@ pub struct Flags { pub bypass_bootstrap_lock: bool, /// whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml - #[arg(global(true), long, value_name = "VALUE")] + #[arg(global = true, long, value_name = "VALUE")] pub llvm_skip_rebuild: Option, /// generate PGO profile with rustc build - #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")] + #[arg(global = true, value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")] pub rust_profile_generate: Option, /// use PGO profile for rustc build - #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")] + #[arg(global = true, value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")] pub rust_profile_use: Option, /// use PGO profile for LLVM build - #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")] + #[arg(global = true, value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")] pub llvm_profile_use: Option, // LLVM doesn't support a custom location for generating profile // information. // // llvm_out/build/profiles/ is the location this writes to. /// generate PGO profile with llvm built for rustc - #[arg(global(true), long)] + #[arg(global = true, long)] pub llvm_profile_generate: bool, /// Enable BOLT link flags - #[arg(global(true), long)] + #[arg(global = true, long)] pub enable_bolt_settings: bool, /// Skip stage0 compiler validation - #[arg(global(true), long)] + #[arg(global = true, long)] pub skip_stage0_validation: bool, /// Additional reproducible artifacts that should be added to the reproducible artifacts archive. - #[arg(global(true), long)] + #[arg(global = true, long)] pub reproducible_artifact: Vec, - #[arg(global(true))] + #[arg(global = true)] /// paths for the subcommand pub paths: Vec, /// override options in config.toml - #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "section.option=value")] + #[arg(global = true, value_hint = clap::ValueHint::Other, long, value_name = "section.option=value")] pub set: Vec, /// arguments passed to subcommands - #[arg(global(true), last(true), value_name = "ARGS")] + #[arg(global = true, last(true), value_name = "ARGS")] pub free_args: Vec, } @@ -192,7 +192,7 @@ impl Flags { struct HelpVerboseOnly { #[arg(short, long)] help: bool, - #[arg(global(true), short, long, action = clap::ArgAction::Count)] + #[arg(global = true, short, long, action = clap::ArgAction::Count)] pub verbose: u8, #[arg(value_enum)] cmd: Kind, @@ -260,16 +260,16 @@ pub enum Subcommand { #[arg(long, requires = "fix")] allow_staged: bool, /// clippy lints to allow - #[arg(global(true), short = 'A', action = clap::ArgAction::Append, value_name = "LINT")] + #[arg(global = true, short = 'A', action = clap::ArgAction::Append, value_name = "LINT")] allow: Vec, /// clippy lints to deny - #[arg(global(true), short = 'D', action = clap::ArgAction::Append, value_name = "LINT")] + #[arg(global = true, short = 'D', action = clap::ArgAction::Append, value_name = "LINT")] deny: Vec, /// clippy lints to warn on - #[arg(global(true), short = 'W', action = clap::ArgAction::Append, value_name = "LINT")] + #[arg(global = true, short = 'W', action = clap::ArgAction::Append, value_name = "LINT")] warn: Vec, /// clippy lints to forbid - #[arg(global(true), short = 'F', action = clap::ArgAction::Append, value_name = "LINT")] + #[arg(global = true, short = 'F', action = clap::ArgAction::Append, value_name = "LINT")] forbid: Vec, }, /// Run cargo fix From 09c076810cb7649e5817f316215010d49e78e8d7 Mon Sep 17 00:00:00 2001 From: Rajveer Date: Sat, 6 Apr 2024 17:29:50 +0530 Subject: [PATCH 099/279] Bootstrap: Check validity of `--target` and `--host` triples before starting a build Resolves #122128 --- src/bootstrap/src/core/sanity.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index e03b1e179084..6ccf29fb6cbe 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -14,6 +14,7 @@ use std::ffi::{OsStr, OsString}; use std::fs; use std::path::PathBuf; use std::process::Command; +use walkdir::WalkDir; use crate::builder::Kind; use crate::core::config::Target; @@ -177,6 +178,34 @@ than building it. continue; } + // Check if there exists a built-in target in the list of supported targets. + let mut has_target = false; + let target_str = target.to_string(); + + let supported_target_list = + output(Command::new(&build.config.initial_rustc).args(["--print", "target-list"])); + + has_target |= supported_target_list.contains(&target_str); + + // If not, check for a valid file location that may have been specified + // by the user for the custom target. + if let Some(custom_target_path) = env::var_os("RUST_TARGET_PATH") { + let mut target_os_str = OsString::from(&target_str); + target_os_str.push(".json"); + // Recursively traverse through nested directories. + let walker = WalkDir::new(custom_target_path).into_iter(); + for entry in walker.filter_map(|e| e.ok()) { + has_target |= entry.file_name() == target_os_str; + } + } + + if !has_target && !["A", "B", "C"].contains(&target_str.as_str()) { + panic!( + "No such target exists in the target list, + specify a correct location of the JSON specification file for custom targets!" + ); + } + if !build.config.dry_run() { cmd_finder.must_have(build.cc(*target)); if let Some(ar) = build.ar(*target) { From fa73ebb303d3c6416c6e67d3184506b6a7883335 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sat, 27 Apr 2024 11:29:24 -0700 Subject: [PATCH 100/279] Unconditionally call really_init This makes miri not diverge in behavior, it fixes running Rust linux-gnu binaries on musl with gcompat, it fixes dlopen edge-cases that cranelift somehow hits, etc. --- library/std/src/sys/pal/unix/args.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/library/std/src/sys/pal/unix/args.rs b/library/std/src/sys/pal/unix/args.rs index acf8100d47f2..afe703bcb2f2 100644 --- a/library/std/src/sys/pal/unix/args.rs +++ b/library/std/src/sys/pal/unix/args.rs @@ -98,12 +98,10 @@ mod imp { } #[inline(always)] - pub unsafe fn init(_argc: isize, _argv: *const *const u8) { - // On Linux-GNU, we rely on `ARGV_INIT_ARRAY` below to initialize - // `ARGC` and `ARGV`. But in Miri that does not actually happen so we - // still initialize here. - #[cfg(any(miri, not(all(target_os = "linux", target_env = "gnu"))))] - really_init(_argc, _argv); + pub unsafe fn init(argc: isize, argv: *const *const u8) { + // on GNU/Linux if we are main then we will init argv and argc twice, it "duplicates work" + // BUT edge-cases are real: only using .init_array can break most emulators, dlopen, etc. + really_init(argc, argv); } /// glibc passes argc, argv, and envp to functions in .init_array, as a non-standard extension. From 17728a9bb2d40537f57c5e7d40e6293529e85a89 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 27 Apr 2024 12:55:28 -0400 Subject: [PATCH 101/279] Record certainty of evaluate_added_goals_and_make_canonical_response call in candidate --- .../rustc_middle/src/traits/solve/inspect.rs | 6 ++++++ .../src/traits/solve/inspect/format.rs | 3 +++ .../src/solve/eval_ctxt/canonical.rs | 2 ++ .../src/solve/inspect/analyse.rs | 21 +++++++++++++++++++ .../src/solve/inspect/build.rs | 17 +++++++++++++++ 5 files changed, 49 insertions(+) diff --git a/compiler/rustc_middle/src/traits/solve/inspect.rs b/compiler/rustc_middle/src/traits/solve/inspect.rs index f2283e71dc87..1b2e2781bfe7 100644 --- a/compiler/rustc_middle/src/traits/solve/inspect.rs +++ b/compiler/rustc_middle/src/traits/solve/inspect.rs @@ -122,6 +122,12 @@ pub enum ProbeStep<'tcx> { /// used whenever there are multiple candidates to prove the /// current goalby . NestedProbe(Probe<'tcx>), + /// A call to `EvalCtxt::evaluate_added_goals_make_canonical_response` with + /// `Certainty` was made. This is the certainty passed in, so it's not unified + /// with the certainty of the `try_evaluate_added_goals` that is done within; + /// if it's `Certainty::Yes`, then we can trust that the candidate is "finished" + /// and we didn't force ambiguity for some reason. + MakeCanonicalResponse { shallow_certainty: Certainty }, } /// What kind of probe we're in. In case the probe represents a candidate, or diff --git a/compiler/rustc_middle/src/traits/solve/inspect/format.rs b/compiler/rustc_middle/src/traits/solve/inspect/format.rs index 98f01fe87724..2e2d1df8d193 100644 --- a/compiler/rustc_middle/src/traits/solve/inspect/format.rs +++ b/compiler/rustc_middle/src/traits/solve/inspect/format.rs @@ -132,6 +132,9 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> { } ProbeStep::EvaluateGoals(eval) => this.format_added_goals_evaluation(eval)?, ProbeStep::NestedProbe(probe) => this.format_probe(probe)?, + ProbeStep::MakeCanonicalResponse { shallow_certainty } => { + writeln!(this.f, "EVALUATE GOALS AND MAKE RESPONSE: {shallow_certainty:?}")? + } } } Ok(()) diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index 9edeb0fa71b9..6722abd709c3 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -98,6 +98,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { previous call to `try_evaluate_added_goals!`" ); + self.inspect.make_canonical_response(certainty); + // When normalizing, we've replaced the expected term with an unconstrained // inference variable. This means that we dropped information which could // have been important. We handle this by instead returning the nested goals diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index f137780c536d..e918f20577cc 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -45,6 +45,7 @@ pub struct InspectCandidate<'a, 'tcx> { nested_goals: Vec>>>, final_state: inspect::CanonicalState<'tcx, ()>, result: QueryResult<'tcx>, + candidate_certainty: Option, } impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { @@ -56,6 +57,19 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { self.result.map(|c| c.value.certainty) } + /// Certainty passed into `evaluate_added_goals_and_make_canonical_response`. + /// + /// If this certainty is `Some(Yes)`, then we must be confident that the candidate + /// must hold iff it's nested goals hold. This is not true if the certainty is + /// `Some(Maybe)`, which suggests we forced ambiguity instead, or if it is `None`, + /// which suggests we may have not assembled any candidates at all. + /// + /// This is *not* the certainty of the candidate's nested evaluation, which can be + /// accessed with [`Self::result`] instead. + pub fn candidate_certainty(&self) -> Option { + self.candidate_certainty + } + /// Visit all nested goals of this candidate without rolling /// back their inference constraints. This function modifies /// the state of the `infcx`. @@ -160,7 +174,9 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { nested_goals: &mut Vec>>>, probe: &inspect::Probe<'tcx>, ) { + let mut candidate_certainty = None; let num_candidates = candidates.len(); + for step in &probe.steps { match step { &inspect::ProbeStep::AddGoal(_source, goal) => nested_goals.push(goal), @@ -172,6 +188,9 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { self.candidates_recur(candidates, nested_goals, probe); nested_goals.truncate(num_goals); } + inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty } => { + assert_eq!(candidate_certainty.replace(*shallow_certainty), None); + } inspect::ProbeStep::EvaluateGoals(_) => (), } } @@ -195,6 +214,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { nested_goals: nested_goals.clone(), final_state: probe.final_state, result, + candidate_certainty, }) } } @@ -206,6 +226,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { nested_goals: nested_goals.clone(), final_state: probe.final_state, result, + candidate_certainty, }); } } diff --git a/compiler/rustc_trait_selection/src/solve/inspect/build.rs b/compiler/rustc_trait_selection/src/solve/inspect/build.rs index c3651517d490..466d0d800601 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/build.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/build.rs @@ -241,6 +241,7 @@ enum WipProbeStep<'tcx> { AddGoal(GoalSource, inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>), EvaluateGoals(WipAddedGoalsEvaluation<'tcx>), NestedProbe(WipProbe<'tcx>), + MakeCanonicalResponse { shallow_certainty: Certainty }, } impl<'tcx> WipProbeStep<'tcx> { @@ -249,6 +250,9 @@ impl<'tcx> WipProbeStep<'tcx> { WipProbeStep::AddGoal(source, goal) => inspect::ProbeStep::AddGoal(source, goal), WipProbeStep::EvaluateGoals(eval) => inspect::ProbeStep::EvaluateGoals(eval.finalize()), WipProbeStep::NestedProbe(probe) => inspect::ProbeStep::NestedProbe(probe.finalize()), + WipProbeStep::MakeCanonicalResponse { shallow_certainty } => { + inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty } + } } } } @@ -530,6 +534,19 @@ impl<'tcx> ProofTreeBuilder<'tcx> { } } + pub fn make_canonical_response(&mut self, shallow_certainty: Certainty) { + match self.as_mut() { + Some(DebugSolver::GoalEvaluationStep(state)) => { + state + .current_evaluation_scope() + .steps + .push(WipProbeStep::MakeCanonicalResponse { shallow_certainty }); + } + None => {} + _ => {} + } + } + pub fn finish_probe(mut self) -> ProofTreeBuilder<'tcx> { match self.as_mut() { None => {} From 26ed429bab12b71891defd0f8191d2b651164f4e Mon Sep 17 00:00:00 2001 From: Veera Date: Sat, 30 Mar 2024 16:40:52 -0400 Subject: [PATCH 102/279] Mention Both HRTB and Generic Lifetime in `E0637` documentation Also, small grammar fix. --- .../src/error_codes/E0637.md | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0637.md b/compiler/rustc_error_codes/src/error_codes/E0637.md index 62d5565df279..9c2a53f51cf2 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0637.md +++ b/compiler/rustc_error_codes/src/error_codes/E0637.md @@ -1,5 +1,5 @@ `'_` lifetime name or `&T` without an explicit lifetime name has been used -on illegal place. +in an illegal place. Erroneous code example: @@ -13,7 +13,14 @@ fn underscore_lifetime<'_>(str1: &'_ str, str2: &'_ str) -> &'_ str { } } -fn and_without_explicit_lifetime() +fn without_explicit_lifetime() +where + T: Iterator, + //^ `&` without an explicit lifetime name +{ +} + +fn without_hrtb() where T: Into<&u32>, //^ `&` without an explicit lifetime name @@ -40,9 +47,15 @@ fn underscore_lifetime<'a>(str1: &'a str, str2: &'a str) -> &'a str { } } -fn and_without_explicit_lifetime<'foo, T>() +fn without_explicit_lifetime<'a, T>() where - T: Into<&'foo u32>, + T: Iterator, +{ +} + +fn without_hrtb() +where + T: for<'foo> Into<&'foo u32>, { } ``` From 7a69a4a5cf750c29ba53ef102dd8a9d148b5a620 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 30 Mar 2024 18:22:53 -0400 Subject: [PATCH 103/279] 1.78 release notes --- RELEASES.md | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 3bd638ff64cc..104ea497ba49 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,123 @@ +Version 1.78.0 (2024-05-02) +========================== + + + +Language +-------- +- [Stabilize `#[cfg(target_abi = ...)]`](https://github.com/rust-lang/rust/pull/119590/) +- [Stabilize the `#[diagnostic]` namespace and `#[diagnostic::on_unimplemented]` attribute](https://github.com/rust-lang/rust/pull/119888/) +- [Make async-fn-in-trait implementable with concrete signatures](https://github.com/rust-lang/rust/pull/120103/) +- [Make matching on NaN a hard error, and remove the rest of `illegal_floating_point_literal_pattern`](https://github.com/rust-lang/rust/pull/116284/) +- [static mut: allow mutable reference to arbitrary types, not just slices and arrays](https://github.com/rust-lang/rust/pull/117614/) +- [Extend `invalid_reference_casting` to include references casting to bigger memory layout](https://github.com/rust-lang/rust/pull/118983/) +- [Add `non_contiguous_range_endpoints` lint for singleton gaps after exclusive ranges](https://github.com/rust-lang/rust/pull/118879/) +- [Add `wasm_c_abi` lint for use of older wasm-bindgen versions](https://github.com/rust-lang/rust/pull/117918/) + This lint currently only works when using Cargo. +- [Update `indirect_structural_match` and `pointer_structural_match` lints to match RFC](https://github.com/rust-lang/rust/pull/120423/) +- [Make non-`PartialEq`-typed consts as patterns a hard error](https://github.com/rust-lang/rust/pull/120805/) +- [Split `refining_impl_trait` lint into `_reachable`, `_internal` variants](https://github.com/rust-lang/rust/pull/121720/) +- [Remove unnecessary type inference when using associated types inside of higher ranked `where`-bounds](https://github.com/rust-lang/rust/pull/119849) +- [Weaken eager detection of cyclic types during type inference](https://github.com/rust-lang/rust/pull/119989) +- [`trait Trait: Auto {}`: allow upcasting from `dyn Trait` to `dyn Auto`](https://github.com/rust-lang/rust/pull/119338) + + + +Compiler +-------- + +- [Made `INVALID_DOC_ATTRIBUTES` lint deny by default](https://github.com/rust-lang/rust/pull/111505/) +- [Increase accuracy of redundant `use` checking](https://github.com/rust-lang/rust/pull/117772/) +- [Suggest moving definition if non-found macro_rules! is defined later](https://github.com/rust-lang/rust/pull/121130/) +- [Lower transmutes from int to pointer type as gep on null](https://github.com/rust-lang/rust/pull/121282/) + +Target changes: + +- [Windows tier 1 targets now require at least Windows 10](https://github.com/rust-lang/rust/pull/115141/) + - [Enable CMPXCHG16B, SSE3, SAHF/LAHF and 128-bit Atomics in tier 1 Windows](https://github.com/rust-lang/rust/pull/120820/) +- [Add `wasm32-wasip1` tier 2 (without host tools) target](https://github.com/rust-lang/rust/pull/120468/) +- [Add `wasm32-wasip2` tier 3 target](https://github.com/rust-lang/rust/pull/119616/) +- [Rename `wasm32-wasi-preview1-threads` to `wasm32-wasip1-threads`](https://github.com/rust-lang/rust/pull/122170/) +- [Add `arm64ec-pc-windows-msvc` tier 3 target](https://github.com/rust-lang/rust/pull/119199/) +- [Add `armv8r-none-eabihf` tier 3 target for the Cortex-R52](https://github.com/rust-lang/rust/pull/110482/) +- [Add `loongarch64-unknown-linux-musl` tier 3 target](https://github.com/rust-lang/rust/pull/121832/) + +Refer to Rust's [platform support page][platform-support-doc] +for more information on Rust's tiered platform support. + + + +Libraries +--------- + +- [Bump Unicode to version 15.1.0, regenerate tables](https://github.com/rust-lang/rust/pull/120777/) +- [Make align_offset, align_to well-behaved in all cases](https://github.com/rust-lang/rust/pull/121201/) +- [PartialEq, PartialOrd: document expectations for transitive chains](https://github.com/rust-lang/rust/pull/115386/) +- [Optimize away poison guards when std is built with panic=abort](https://github.com/rust-lang/rust/pull/100603/) +- [Replace pthread `RwLock` with custom implementation](https://github.com/rust-lang/rust/pull/110211/) +- [Implement unwind safety for Condvar on all platforms](https://github.com/rust-lang/rust/pull/121768/) +- [Add ASCII fast-path for `char::is_grapheme_extended`](https://github.com/rust-lang/rust/pull/121138/) + + + +Stabilized APIs +--------------- + +- [`impl Read for &Stdin`](https://doc.rust-lang.org/stable/std/io/struct.Stdin.html#impl-Read-for-%26Stdin) +- [Accept non `'static` lifetimes for several `std::error::Error` related implementations](https://github.com/rust-lang/rust/pull/113833/) +- [Make `impl` impl take `?Sized`](https://github.com/rust-lang/rust/pull/114655/) +- [`impl From for io::Error`](https://doc.rust-lang.org/stable/std/io/struct.Error.html#impl-From%3CTryReserveError%3E-for-Error) + +These APIs are now stable in const contexts: + +- [`Barrier::new()`](https://doc.rust-lang.org/stable/std/sync/struct.Barrier.html#method.new) + + + +Cargo +----- + +- [Stabilize lockfile v4](https://github.com/rust-lang/cargo/pull/12852/) +- [Respect `rust-version` when generating lockfile](https://github.com/rust-lang/cargo/pull/12861/) +- [Control `--charset` via auto-detecting config value](https://github.com/rust-lang/cargo/pull/13337/) +- [Support `target..rustdocflags` officially](https://github.com/rust-lang/cargo/pull/13197/) +- [Stabilize global cache data tracking](https://github.com/rust-lang/cargo/pull/13492/) + + + +Misc +---- + +- [rustdoc: add `--test-builder-wrapper` arg to support wrappers such as RUSTC_WRAPPER when building doctests](https://github.com/rust-lang/rust/pull/114651/) + + + +Compatibility Notes +------------------- + +- [Many unsafe precondition checks now run for user code with debug assertions enabled](https://github.com/rust-lang/rust/pull/120594/) + This change helps users catch undefined behavior in their code, though the details of how much is checked are generally not stable. +- [riscv only supports split_debuginfo=off for now](https://github.com/rust-lang/rust/pull/120518/) +- [Consistently check bounds on hidden types of `impl Trait`](https://github.com/rust-lang/rust/pull/121679) +- [Change equality of higher ranked types to not rely on subtyping](https://github.com/rust-lang/rust/pull/118247) +- [When called, additionally check bounds on normalized function return type](https://github.com/rust-lang/rust/pull/118882) +- [Expand coverage for `arithmetic_overflow` lint](https://github.com/rust-lang/rust/pull/119432/) + + + +Internal Changes +---------------- + +These changes do not affect any public interfaces of Rust, but they represent +significant improvements to the performance or internals of rustc and related +tools. + +- [Update to LLVM 18](https://github.com/rust-lang/rust/pull/120055/) +- [Build `rustc` with 1CGU on `x86_64-pc-windows-msvc`](https://github.com/rust-lang/rust/pull/112267/) +- [Build `rustc` with 1CGU on `x86_64-apple-darwin`](https://github.com/rust-lang/rust/pull/112268/) +- [Introduce `run-make` V2 infrastructure, a `run_make_support` library and port over 2 tests as example](https://github.com/rust-lang/rust/pull/113026/) +- [Windows: Implement condvar, mutex and rwlock using futex](https://github.com/rust-lang/rust/pull/121956/) + Version 1.77.2 (2024-04-09) =========================== From a7696ed4abcbaf953be35e62fdb42be82b2e94de Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 27 Apr 2024 19:03:50 -0400 Subject: [PATCH 104/279] Bump version to 1.80 --- src/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version b/src/version index b3a8c61e6a86..aaceec04e040 100644 --- a/src/version +++ b/src/version @@ -1 +1 @@ -1.79.0 +1.80.0 From b700d9c9284a3a2423fb4cd26c31f86b6ca2f41d Mon Sep 17 00:00:00 2001 From: Kornel Date: Sun, 28 Apr 2024 00:15:56 +0100 Subject: [PATCH 105/279] clippy::single_match(_else) may be machine applicable --- clippy_lints/src/matches/single_match.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/matches/single_match.rs b/clippy_lints/src/matches/single_match.rs index a0db8e2db1f8..98dbe3c4f004 100644 --- a/clippy_lints/src/matches/single_match.rs +++ b/clippy_lints/src/matches/single_match.rs @@ -75,7 +75,7 @@ fn report_single_pattern( ) { let lint = if els.is_some() { SINGLE_MATCH_ELSE } else { SINGLE_MATCH }; let ctxt = expr.span.ctxt(); - let mut app = Applicability::HasPlaceholders; + let mut app = Applicability::MachineApplicable; let els_str = els.map_or(String::new(), |els| { format!(" else {}", expr_block(cx, els, ctxt, "..", Some(expr.span), &mut app)) }); From 1ba00d9cb2fcfef464b6a188fa3a7543c66eecaa Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sun, 21 Apr 2024 17:19:15 +0200 Subject: [PATCH 106/279] put FD validity behind late debug_asserts checking uses the same machinery as assert_unsafe_precondition --- library/std/src/os/fd/owned.rs | 14 ++------- library/std/src/sys/pal/unix/fs.rs | 47 ++++++++++++++++++------------ 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 8c421540af40..8c7fc4cb2e45 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -177,17 +177,9 @@ impl Drop for OwnedFd { // opened after we closed ours. #[cfg(not(target_os = "hermit"))] { - use crate::sys::os::errno; - // ideally this would use assert_unsafe_precondition!, but that's only in core - if cfg!(debug_assertions) { - // close() can bubble up error codes from FUSE which can send semantically - // inappropriate error codes including EBADF. - // So we check file flags instead which live on the file descriptor and not the underlying file. - // The downside is that it costs an extra syscall, so we only do it for debug. - if libc::fcntl(self.fd, libc::F_GETFD) == -1 && errno() == libc::EBADF { - rtabort!("IO Safety violation: owned file descriptor already closed"); - } - } + #[cfg(unix)] + crate::sys::fs::debug_assert_fd_is_open(self.fd); + let _ = libc::close(self.fd); } #[cfg(target_os = "hermit")] diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 2d57a9d81c91..0a86d28c2e3b 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -868,28 +868,39 @@ impl Iterator for ReadDir { } } +/// Aborts the process if a file desceriptor is not open, if debug asserts are enabled +/// +/// Many IO syscalls can't be fully trusted about EBADF error codes because those +/// might get bubbled up from a remote FUSE server rather than the file descriptor +/// in the current process being invalid. +/// +/// So we check file flags instead which live on the file descriptor and not the underlying file. +/// The downside is that it costs an extra syscall, so we only do it for debug. +#[inline] +pub(crate) fn debug_assert_fd_is_open(fd: RawFd) { + use crate::sys::os::errno; + + // this is similar to assert_unsafe_precondition!() but it doesn't require const + if core::ub_checks::check_library_ub() { + if unsafe { libc::fcntl(fd, libc::F_GETFD) } == -1 && errno() == libc::EBADF { + rtabort!("IO Safety violation: owned file descriptor already closed"); + } + } +} + impl Drop for Dir { fn drop(&mut self) { - // ideally this would use assert_unsafe_precondition!, but that's only in core - #[cfg(all( - debug_assertions, - not(any( - target_os = "redox", - target_os = "nto", - target_os = "vita", - target_os = "hurd", - )) - ))] + // dirfd isn't supported everywhere + #[cfg(not(any( + miri, + target_os = "redox", + target_os = "nto", + target_os = "vita", + target_os = "hurd", + )))] { - use crate::sys::os::errno; - // close() can bubble up error codes from FUSE which can send semantically - // inappropriate error codes including EBADF. - // So we check file flags instead which live on the file descriptor and not the underlying file. - // The downside is that it costs an extra syscall, so we only do it for debug. let fd = unsafe { libc::dirfd(self.0) }; - if unsafe { libc::fcntl(fd, libc::F_GETFD) } == -1 && errno() == libc::EBADF { - rtabort!("IO Safety violation: DIR*'s owned file descriptor already closed"); - } + debug_assert_fd_is_open(fd); } let r = unsafe { libc::closedir(self.0) }; assert!( From 6faedd381b045079245c66970e66a5aa79af3475 Mon Sep 17 00:00:00 2001 From: yukang Date: Sat, 27 Apr 2024 16:21:10 +0800 Subject: [PATCH 107/279] Fix the assertion crash from rustdoc document indent widths --- compiler/rustc_resolve/src/rustdoc.rs | 25 ++++++++++++++----------- tests/rustdoc/resolve-ice-124363.rs | 7 +++++++ 2 files changed, 21 insertions(+), 11 deletions(-) create mode 100644 tests/rustdoc/resolve-ice-124363.rs diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 0bc7579918cc..aace0f3fef9f 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -6,8 +6,8 @@ use rustc_middle::ty::TyCtxt; use rustc_span::def_id::DefId; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{InnerSpan, Span, DUMMY_SP}; +use std::mem; use std::ops::Range; -use std::{cmp, mem}; #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum DocFragmentKind { @@ -129,17 +129,20 @@ pub fn unindent_doc_fragments(docs: &mut [DocFragment]) { let Some(min_indent) = docs .iter() .map(|fragment| { - fragment.doc.as_str().lines().fold(usize::MAX, |min_indent, line| { - if line.chars().all(|c| c.is_whitespace()) { - min_indent - } else { + fragment + .doc + .as_str() + .lines() + .filter(|line| line.chars().any(|c| !c.is_whitespace())) + .map(|line| { // Compare against either space or tab, ignoring whether they are // mixed or not. let whitespace = line.chars().take_while(|c| *c == ' ' || *c == '\t').count(); - cmp::min(min_indent, whitespace) - + if fragment.kind == DocFragmentKind::SugaredDoc { 0 } else { add } - } - }) + whitespace + + (if fragment.kind == DocFragmentKind::SugaredDoc { 0 } else { add }) + }) + .min() + .unwrap_or(usize::MAX) }) .min() else { @@ -151,13 +154,13 @@ pub fn unindent_doc_fragments(docs: &mut [DocFragment]) { continue; } - let min_indent = if fragment.kind != DocFragmentKind::SugaredDoc && min_indent > 0 { + let indent = if fragment.kind != DocFragmentKind::SugaredDoc && min_indent > 0 { min_indent - add } else { min_indent }; - fragment.indent = min_indent; + fragment.indent = indent; } } diff --git a/tests/rustdoc/resolve-ice-124363.rs b/tests/rustdoc/resolve-ice-124363.rs new file mode 100644 index 000000000000..111916cc5905 --- /dev/null +++ b/tests/rustdoc/resolve-ice-124363.rs @@ -0,0 +1,7 @@ +/** +*/ +pub mod A { + #![doc = "{ + Foo { }, + }"] +} From 57a5f34ccb4973d22ce017d3d9144adbf1acb46f Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 28 Apr 2024 10:08:08 +0300 Subject: [PATCH 108/279] handle the targets that are missing in stage0 Signed-off-by: onur-ozkan --- src/bootstrap/src/core/sanity.rs | 57 +++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 6ccf29fb6cbe..0c069a540696 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -26,6 +26,17 @@ pub struct Finder { path: OsString, } +// During sanity checks, we search for target names to determine if they exist in the compiler's built-in +// target list (`rustc --print target-list`). While a target name may be present in the stage2 compiler, +// it might not yet be included in stage0. In such cases, we handle the targets missing from stage0 in this list. +// +// Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap). +const STAGE0_MISSING_TARGETS: &[&str] = &[ + // just a dummy comment so the list doesn't get onelined + "aarch64-apple-visionos", + "aarch64-apple-visionos-sim", +]; + impl Finder { pub fn new() -> Self { Self { cache: HashMap::new(), path: env::var_os("PATH").unwrap_or_default() } @@ -178,32 +189,40 @@ than building it. continue; } - // Check if there exists a built-in target in the list of supported targets. - let mut has_target = false; let target_str = target.to_string(); - let supported_target_list = - output(Command::new(&build.config.initial_rustc).args(["--print", "target-list"])); + // Ignore fake targets that are only used for unit tests in bootstrap. + if !["A", "B", "C"].contains(&target_str.as_str()) { + let mut has_target = false; - has_target |= supported_target_list.contains(&target_str); + let supported_target_list = + output(Command::new(&build.config.initial_rustc).args(["--print", "target-list"])); - // If not, check for a valid file location that may have been specified - // by the user for the custom target. - if let Some(custom_target_path) = env::var_os("RUST_TARGET_PATH") { - let mut target_os_str = OsString::from(&target_str); - target_os_str.push(".json"); - // Recursively traverse through nested directories. - let walker = WalkDir::new(custom_target_path).into_iter(); - for entry in walker.filter_map(|e| e.ok()) { - has_target |= entry.file_name() == target_os_str; + // Check if it's a built-in target. + has_target |= supported_target_list.contains(&target_str); + has_target |= STAGE0_MISSING_TARGETS.contains(&target_str.as_str()); + + if !has_target { + // This might also be a custom target, so check the target file that could have been specified by the user. + if let Some(custom_target_path) = env::var_os("RUST_TARGET_PATH") { + let mut target_filename = OsString::from(&target_str); + // Target filename ends with `.json`. + target_filename.push(".json"); + + // Recursively traverse through nested directories. + let walker = WalkDir::new(custom_target_path).into_iter(); + for entry in walker.filter_map(|e| e.ok()) { + has_target |= entry.file_name() == target_filename; + } + } } - } - if !has_target && !["A", "B", "C"].contains(&target_str.as_str()) { - panic!( - "No such target exists in the target list, + if !has_target { + panic!( + "No such target exists in the target list, specify a correct location of the JSON specification file for custom targets!" - ); + ); + } } if !build.config.dry_run() { From 4aafec1bc1c1cb860f38fad9e4d11f37f38c573f Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Sun, 28 Apr 2024 13:09:36 +0530 Subject: [PATCH 109/279] Rename `inihibit_union_abi_opt()` to `inihibits_union_abi_opt()` The present tense makes it read more naturally at use site i.e. "this repr _inhibits_ optimizations" --- compiler/rustc_abi/src/layout.rs | 2 +- compiler/rustc_abi/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 3584eea0f149..a95ef4c460f4 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -251,7 +251,7 @@ pub trait LayoutCalculator { // If all the non-ZST fields have the same ABI and union ABI optimizations aren't // disabled, we can use that common ABI for the union as a whole. struct AbiMismatch; - let mut common_non_zst_abi_and_align = if repr.inhibit_union_abi_opt() { + let mut common_non_zst_abi_and_align = if repr.inhibits_union_abi_opt() { // Can't optimize Err(AbiMismatch) } else { diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 7439af7aed3e..a46148242d5c 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -155,7 +155,7 @@ impl ReprOptions { } /// Returns `true` if this `#[repr()]` should inhibit union ABI optimisations. - pub fn inhibit_union_abi_opt(&self) -> bool { + pub fn inhibits_union_abi_opt(&self) -> bool { self.c() } } From c968b8b777a873a086338dc797c173130c639a04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 27 Apr 2024 14:20:51 +0200 Subject: [PATCH 110/279] add test for ICE: tcx.resolutions(()) is not supported for local crate -Zunpretty=mir on invalid module path with staged_ap Fixes https://github.com/rust-lang/rust/issues/108697 --- tests/ui/unpretty/staged-api-invalid-path-108697.rs | 9 +++++++++ tests/ui/unpretty/staged-api-invalid-path-108697.stderr | 8 ++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/ui/unpretty/staged-api-invalid-path-108697.rs create mode 100644 tests/ui/unpretty/staged-api-invalid-path-108697.stderr diff --git a/tests/ui/unpretty/staged-api-invalid-path-108697.rs b/tests/ui/unpretty/staged-api-invalid-path-108697.rs new file mode 100644 index 000000000000..127fe523082c --- /dev/null +++ b/tests/ui/unpretty/staged-api-invalid-path-108697.rs @@ -0,0 +1,9 @@ +// issue: rust-lang/rust#108697 +// ICE: tcx.resolutions(()) is not supported for local crate -Zunpretty=mir +// on invalid module path with staged_api +//@ compile-flags: -Zunpretty=mir + +#![feature(staged_api)] +#[path = "lol"] +mod foo; +//~^ ERROR couldn't read diff --git a/tests/ui/unpretty/staged-api-invalid-path-108697.stderr b/tests/ui/unpretty/staged-api-invalid-path-108697.stderr new file mode 100644 index 000000000000..9c6d1a042d75 --- /dev/null +++ b/tests/ui/unpretty/staged-api-invalid-path-108697.stderr @@ -0,0 +1,8 @@ +error: couldn't read $DIR/lol: No such file or directory (os error 2) + --> $DIR/staged-api-invalid-path-108697.rs:8:1 + | +LL | mod foo; + | ^^^^^^^^ + +error: aborting due to 1 previous error + From c32e2fe1796feb6c8c0cd3f0008bc4c3efc9106f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 27 Apr 2024 14:26:43 +0200 Subject: [PATCH 111/279] add test for https://github.com/rust-lang/rust/issues/109812 --- tests/crashes/109812.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/crashes/109812.rs diff --git a/tests/crashes/109812.rs b/tests/crashes/109812.rs new file mode 100644 index 000000000000..c29b87465215 --- /dev/null +++ b/tests/crashes/109812.rs @@ -0,0 +1,22 @@ +//@ known-bug: #109812 + +#![warn(rust_2021_incompatible_closure_captures)] + +enum Either { + One(X), + Two(X), +} + +struct X(Y); + +struct Y; + +fn move_into_fnmut() { + let x = X(Y); + + consume_fnmut(|| { + let Either::Two(ref mut _t) = x; + + let X(mut _t) = x; + }); +} From 012f9e26acbdab1c34b8ba40ccb44788a822d1d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 27 Apr 2024 14:32:47 +0200 Subject: [PATCH 112/279] add test for Inconsistent rustc_transmute::is_transmutable(...) result, got Yes Fixes https://github.com/rust-lang/rust/issues/110969 --- .../transmutable-ice-110969.rs | 32 +++++++++++++++ .../transmutable-ice-110969.stderr | 39 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs create mode 100644 tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr diff --git a/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs new file mode 100644 index 000000000000..68b8b4898168 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs @@ -0,0 +1,32 @@ +// ICE Inconsistent rustc_transmute::is_transmutable(...) result, got Yes +// issue: rust-lang/rust#110969 +#![feature(adt_const_params, generic_const_exprs, transmutability)] +#![allow(incomplete_features, unstable_features)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom, + //~^ ERROR trait takes at most 2 generic arguments but 3 generic arguments were supplied + { + } +} + +fn via_associated_const() { + struct Context; + #[repr(C)] + struct Src; + #[repr(C)] + struct Dst; + + trait Trait { + const FALSE: bool = assert::is_transmutable::(); + //~^ ERROR mismatched types + //~| ERROR `Src` cannot be safely transmuted into `Dst` + //~| ERROR mismatched types + } +} + +pub fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr new file mode 100644 index 000000000000..1dbacaee3c2d --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr @@ -0,0 +1,39 @@ +error[E0107]: trait takes at most 2 generic arguments but 3 generic arguments were supplied + --> $DIR/transmutable-ice-110969.rs:11:14 + | +LL | Dst: BikeshedIntrinsicFrom, + | ^^^^^^^^^^^^^^^^^^^^^ ------ help: remove this generic argument + | | + | expected at most 2 generic arguments + +error[E0308]: mismatched types + --> $DIR/transmutable-ice-110969.rs:25:74 + | +LL | const FALSE: bool = assert::is_transmutable::(); + | ^^ expected `Assume`, found `()` + +error[E0277]: `Src` cannot be safely transmuted into `Dst` + --> $DIR/transmutable-ice-110969.rs:25:60 + | +LL | const FALSE: bool = assert::is_transmutable::(); + | ^^^ `Dst` may carry safety invariants + | +note: required by a bound in `is_transmutable` + --> $DIR/transmutable-ice-110969.rs:11:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this function +LL | where +LL | Dst: BikeshedIntrinsicFrom, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0308]: mismatched types + --> $DIR/transmutable-ice-110969.rs:25:29 + | +LL | const FALSE: bool = assert::is_transmutable::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0107, E0277, E0308. +For more information about an error, try `rustc --explain E0107`. From f483971b87bae0c236b41185f298e4524155e2d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 27 Apr 2024 14:42:38 +0200 Subject: [PATCH 113/279] add test for ICE failed to resolve instance for <[f32; 2] as CrossProduct Fixes https://github.com/rust-lang/rust/issues/111667 --- .../failed-to-resolve-instance-ice-111667.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/ui/const-generics/generic_const_exprs/failed-to-resolve-instance-ice-111667.rs diff --git a/tests/ui/const-generics/generic_const_exprs/failed-to-resolve-instance-ice-111667.rs b/tests/ui/const-generics/generic_const_exprs/failed-to-resolve-instance-ice-111667.rs new file mode 100644 index 000000000000..c547b54e16b0 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/failed-to-resolve-instance-ice-111667.rs @@ -0,0 +1,18 @@ +// issue rust-lang/rust#111667 +// ICE failed to resolve instance for <[f32; 2] as CrossProduct .. +//@ check-pass + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +pub trait CrossProduct<'a, T, R> { + fn cross(&'a self, t: &'a T) -> R; +} + +impl<'a, T, U, const N: usize> CrossProduct<'a, [U; N], [(&'a T, &'a U); N * N]> for [T; N] { + fn cross(&'a self, us: &'a [U; N]) -> [(&'a T, &'a U); N * N] { + std::array::from_fn(|i| (&self[i / N], &us[i % N])) + } +} + +pub fn main() {} From bb4769532b721d3c6355ac11910c273724a77967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 27 Apr 2024 14:52:52 +0200 Subject: [PATCH 114/279] add test for const generic ty's with lifetimes cause opaque types to ICE Fixes https://github.com/rust-lang/rust/issues/111911 --- ...ith_non-universal_region_substs_ice-111911.rs | 13 +++++++++++++ ...non-universal_region_substs_ice-111911.stderr | 16 ++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.rs create mode 100644 tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.stderr diff --git a/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.rs b/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.rs new file mode 100644 index 000000000000..05bd0d91168a --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.rs @@ -0,0 +1,13 @@ +//@ edition:2021 +// issues rust-lang/rust#111911 +// test for ICE opaque type with non-universal region substs + +#![feature(adt_const_params)] +#![allow(incomplete_features)] + +pub async fn foo() {} +//~^ ERROR const parameter `X` is part of concrete type but not used in parameter list for the `impl Trait` type alias +//~| ERROR const parameter `X` is part of concrete type but not used in parameter list for the `impl Trait` type alias +fn bar() -> impl Sized {} + +pub fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.stderr b/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.stderr new file mode 100644 index 000000000000..1bdb9cd9501a --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.stderr @@ -0,0 +1,16 @@ +error: const parameter `X` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/opaque_type_with_non-universal_region_substs_ice-111911.rs:8:43 + | +LL | pub async fn foo() {} + | ^^ + +error: const parameter `X` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/opaque_type_with_non-universal_region_substs_ice-111911.rs:8:43 + | +LL | pub async fn foo() {} + | ^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + From 27338f2fe01c4632aa32ba29f8f5c801afe26471 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 27 Apr 2024 15:04:16 +0200 Subject: [PATCH 115/279] add test for ice future has no bound vars. Fixes https://github.com/rust-lang/rust/issues/112347 --- .../future-no-bound-vars-ice-112347.rs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs diff --git a/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs b/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs new file mode 100644 index 000000000000..dc4dc9e220d5 --- /dev/null +++ b/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs @@ -0,0 +1,29 @@ +// issue: rust-lang/rust#112347 +// ICE future has no bound vars +//@ edition:2021 +//@ check-pass + +#![feature(type_alias_impl_trait)] + +use std::future::Future; + +type Fut<'a> = impl Future + 'a; + +fn foo<'a>(_: &()) -> Fut<'_> { + async {} +} + +trait Test { + fn hello(); +} + +impl Test for () +where + for<'a> Fut<'a>: Future, +{ + fn hello() {} +} + +fn main() { + <()>::hello(); +} From f536a06a5aaf99b0c25de577ad102cdd1c0e59f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 27 Apr 2024 15:17:45 +0200 Subject: [PATCH 116/279] add test for ice expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr Fixes https://github.com/rust-lang/rust/issues/113776 --- ...to-be-a-closure-or-coroutine-ice-113776.rs | 23 +++++++ ...e-a-closure-or-coroutine-ice-113776.stderr | 68 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr diff --git a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs new file mode 100644 index 000000000000..4bea3ad87f5e --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs @@ -0,0 +1,23 @@ +// issue: rust-lang/rust#113776 +// ice: expected type of closure body to be a closure or coroutine +//@ edition: 2021 +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +use core::ops::SubAssign; + +fn f( + data: &[(); { + let f: F = async { 1 }; + //~^ ERROR cannot find type `F` in this scope + + 1 + }], +) -> impl Iterator { +//~^ ERROR the type parameter `Rhs` must be explicitly specified +//~| ERROR `()` is not an iterator +//~| ERROR trait objects must include the `dyn` keyword +//~| ERROR the type parameter `Rhs` must be explicitly specified [E0393] +} + +pub fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr new file mode 100644 index 000000000000..be79450a3ce3 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr @@ -0,0 +1,68 @@ +error[E0412]: cannot find type `F` in this scope + --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:11:17 + | +LL | let f: F = async { 1 }; + | ^ + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + | + = note: similarly named trait `Fn` defined here + | +help: a trait with a similar name exists + | +LL | let f: Fn = async { 1 }; + | ~~ +help: you might be missing a type parameter + | +LL | fn f( + | +++ + +error[E0393]: the type parameter `Rhs` must be explicitly specified + --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:27 + | +LL | ) -> impl Iterator { + | ^^^^^^^^^ help: set the type parameter to the desired type: `SubAssign` + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | + = note: type parameter `Rhs` must be specified for this + | + = note: because of the default `Self` reference, type parameters must be specified on object types + +error[E0393]: the type parameter `Rhs` must be explicitly specified + --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:27 + | +LL | ) -> impl Iterator { + | ^^^^^^^^^ help: set the type parameter to the desired type: `SubAssign` + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | + = note: type parameter `Rhs` must be specified for this + | + = note: because of the default `Self` reference, type parameters must be specified on object types + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0277]: `()` is not an iterator + --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:6 + | +LL | ) -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator + | + = help: the trait `Iterator` is not implemented for `()` + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:27 + | +LL | ) -> impl Iterator { + | ^^^^^^^^^ + | +help: add `dyn` keyword before this trait + | +LL | ) -> impl Iterator { + | +++ +help: you might have meant to write a bound here + | +LL | ) -> impl Iterator { + | ~ + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0277, E0393, E0412, E0782. +For more information about an error, try `rustc --explain E0277`. From a15996c9f1b191f144ad0b201f41a4e07f803c42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 28 Apr 2024 11:03:38 +0200 Subject: [PATCH 117/279] try to fix tests on windows where the "file not found" error is different from linux --- tests/ui/unpretty/staged-api-invalid-path-108697.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/unpretty/staged-api-invalid-path-108697.rs b/tests/ui/unpretty/staged-api-invalid-path-108697.rs index 127fe523082c..1b6ef2491914 100644 --- a/tests/ui/unpretty/staged-api-invalid-path-108697.rs +++ b/tests/ui/unpretty/staged-api-invalid-path-108697.rs @@ -2,7 +2,7 @@ // ICE: tcx.resolutions(()) is not supported for local crate -Zunpretty=mir // on invalid module path with staged_api //@ compile-flags: -Zunpretty=mir - +//@ normalize-stderr-test: "The system cannot find the file specified." -> "No such file or directory" #![feature(staged_api)] #[path = "lol"] mod foo; From ef1b0210bd6210c3a5f68420ca69307c941ee2c1 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Sun, 28 Apr 2024 15:13:41 +0200 Subject: [PATCH 118/279] remove myself from vacation --- triagebot.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 901977da25be..4d66b728b76d 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -20,7 +20,6 @@ new_pr = true [assign] contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md" users_on_vacation = [ - "y21", "matthiaskrgr", "giraffate", "Centri3", From a0a84429a5f833381e376c216e54942838106f51 Mon Sep 17 00:00:00 2001 From: George Bateman Date: Sun, 28 Apr 2024 14:13:08 +0100 Subject: [PATCH 119/279] Remove direct dependencies on lazy_static, once_cell and byteorder The functionality of all three crates is now available in the standard library. --- Cargo.lock | 8 ------- src/librustdoc/Cargo.toml | 2 -- src/librustdoc/html/markdown.rs | 6 ++--- .../html/render/search_index/encode.rs | 23 +++++++++---------- src/tools/jsondocck/Cargo.toml | 1 - src/tools/jsondocck/src/main.rs | 9 ++++---- src/tools/linkchecker/Cargo.toml | 1 - src/tools/linkchecker/main.rs | 12 ++++++---- src/tools/miri/Cargo.toml | 1 - src/tools/miri/tests/ui.rs | 22 ++++++++++-------- src/tools/rustfmt/Cargo.toml | 1 - src/tools/rustfmt/src/comment.rs | 20 +++++----------- src/tools/rustfmt/src/lib.rs | 10 +++++--- .../rustfmt/src/test/configuration_snippet.rs | 22 ++++++------------ src/tools/suggest-tests/Cargo.toml | 1 - src/tools/suggest-tests/src/lib.rs | 4 ++-- .../suggest-tests/src/static_suggestions.rs | 8 +++++-- src/tools/tidy/Cargo.toml | 1 - src/tools/tidy/src/features.rs | 19 ++++----------- src/tools/tidy/src/fluent_alphabetical.rs | 8 +++---- src/tools/tidy/src/fluent_used.rs | 7 +----- src/tools/tidy/src/lib.rs | 7 ++++++ src/tools/tidy/src/style.rs | 18 +++++---------- src/tools/tidy/src/ui_tests.rs | 10 ++------ 24 files changed, 91 insertions(+), 130 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ac6e7974a127..233f4af1e24b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2113,7 +2113,6 @@ dependencies = [ "fs-err", "getopts", "jsonpath_lib", - "once_cell", "regex", "serde_json", "shlex", @@ -2232,7 +2231,6 @@ name = "linkchecker" version = "0.1.0" dependencies = [ "html5ever", - "once_cell", "regex", ] @@ -2491,7 +2489,6 @@ dependencies = [ "directories", "getrandom", "jemalloc-sys", - "lazy_static", "libc", "libffi", "libloading", @@ -4791,12 +4788,10 @@ dependencies = [ "arrayvec", "askama", "base64", - "byteorder", "expect-test", "indexmap", "itertools 0.12.1", "minifier", - "once_cell", "regex", "rustdoc-json-types", "serde", @@ -4889,7 +4884,6 @@ dependencies = [ "getopts", "ignore", "itertools 0.11.0", - "lazy_static", "regex", "rustfmt-config_proc_macro", "serde", @@ -5351,7 +5345,6 @@ version = "0.1.0" dependencies = [ "build_helper", "glob", - "once_cell", ] [[package]] @@ -5596,7 +5589,6 @@ version = "0.1.0" dependencies = [ "cargo_metadata 0.15.4", "ignore", - "lazy_static", "miropt-test-tools", "regex", "rustc-hash", diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 9a23811ed3f9..31222f213d80 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -10,11 +10,9 @@ path = "lib.rs" arrayvec = { version = "0.7", default-features = false } askama = { version = "0.12", default-features = false, features = ["config"] } base64 = "0.21.7" -byteorder = "1.5" itertools = "0.12" indexmap = "2" minifier = "0.3.0" -once_cell = "1.10.0" regex = "1" rustdoc-json-types = { path = "../rustdoc-json-types" } serde_json = "1.0" diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 64f0e096cd02..5c5651f3ef0e 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -35,13 +35,13 @@ use rustc_resolve::rustdoc::may_be_doc_link; use rustc_span::edition::Edition; use rustc_span::{Span, Symbol}; -use once_cell::sync::Lazy; use std::borrow::Cow; use std::collections::VecDeque; use std::fmt::Write; use std::iter::Peekable; use std::ops::{ControlFlow, Range}; use std::str::{self, CharIndices}; +use std::sync::OnceLock; use crate::clean::RenderedLink; use crate::doctest; @@ -1994,7 +1994,7 @@ pub struct IdMap { } // The map is pre-initialized and cloned each time to avoid reinitializing it repeatedly. -static DEFAULT_ID_MAP: Lazy, usize>> = Lazy::new(|| init_id_map()); +static DEFAULT_ID_MAP: OnceLock, usize>> = OnceLock::new(); fn init_id_map() -> FxHashMap, usize> { let mut map = FxHashMap::default(); @@ -2051,7 +2051,7 @@ fn init_id_map() -> FxHashMap, usize> { impl IdMap { pub fn new() -> Self { - IdMap { map: DEFAULT_ID_MAP.clone() } + IdMap { map: DEFAULT_ID_MAP.get_or_init(init_id_map).clone() } } pub(crate) fn derive + ToString>(&mut self, candidate: S) -> String { diff --git a/src/librustdoc/html/render/search_index/encode.rs b/src/librustdoc/html/render/search_index/encode.rs index 54407c614c4c..8d715814faad 100644 --- a/src/librustdoc/html/render/search_index/encode.rs +++ b/src/librustdoc/html/render/search_index/encode.rs @@ -166,13 +166,12 @@ pub(crate) fn write_bitmap_to_bytes( containers.push(container); } // https://github.com/RoaringBitmap/RoaringFormatSpec - use byteorder::{WriteBytesExt, LE}; const SERIAL_COOKIE_NO_RUNCONTAINER: u32 = 12346; const SERIAL_COOKIE: u32 = 12347; const NO_OFFSET_THRESHOLD: u32 = 4; let size: u32 = containers.len().try_into().unwrap(); let start_offset = if has_run { - out.write_u32::(SERIAL_COOKIE | ((size - 1) << 16))?; + out.write_all(&u32::to_le_bytes(SERIAL_COOKIE | ((size - 1) << 16)))?; for set in containers.chunks(8) { let mut b = 0; for (i, container) in set.iter().enumerate() { @@ -180,7 +179,7 @@ pub(crate) fn write_bitmap_to_bytes( b |= 1 << i; } } - out.write_u8(b)?; + out.write_all(&[b])?; } if size < NO_OFFSET_THRESHOLD { 4 + 4 * size + ((size + 7) / 8) @@ -188,21 +187,21 @@ pub(crate) fn write_bitmap_to_bytes( 4 + 8 * size + ((size + 7) / 8) } } else { - out.write_u32::(SERIAL_COOKIE_NO_RUNCONTAINER)?; - out.write_u32::(containers.len().try_into().unwrap())?; + out.write_all(&u32::to_le_bytes(SERIAL_COOKIE_NO_RUNCONTAINER))?; + out.write_all(&u32::to_le_bytes(containers.len().try_into().unwrap()))?; 4 + 4 + 4 * size + 4 * size }; for (&key, container) in keys.iter().zip(&containers) { // descriptive header let key: u32 = key.into(); let count: u32 = container.popcount() - 1; - out.write_u32::((count << 16) | key)?; + out.write_all(&u32::to_le_bytes((count << 16) | key))?; } if !has_run || size >= NO_OFFSET_THRESHOLD { // offset header let mut starting_offset = start_offset; for container in &containers { - out.write_u32::(starting_offset)?; + out.write_all(&u32::to_le_bytes(starting_offset))?; starting_offset += match container { Container::Bits(_) => 8192u32, Container::Array(array) => u32::try_from(array.len()).unwrap() * 2, @@ -214,19 +213,19 @@ pub(crate) fn write_bitmap_to_bytes( match container { Container::Bits(bits) => { for chunk in bits.iter() { - out.write_u64::(*chunk)?; + out.write_all(&u64::to_le_bytes(*chunk))?; } } Container::Array(array) => { for value in array.iter() { - out.write_u16::(*value)?; + out.write_all(&u16::to_le_bytes(*value))?; } } Container::Run(runs) => { - out.write_u16::((runs.len()).try_into().unwrap())?; + out.write_all(&u16::to_le_bytes(runs.len().try_into().unwrap()))?; for (start, lenm1) in runs.iter().copied() { - out.write_u16::(start)?; - out.write_u16::(lenm1)?; + out.write_all(&u16::to_le_bytes(start))?; + out.write_all(&u16::to_le_bytes(lenm1))?; } } } diff --git a/src/tools/jsondocck/Cargo.toml b/src/tools/jsondocck/Cargo.toml index 6326a9b1e79c..e1eb6d056651 100644 --- a/src/tools/jsondocck/Cargo.toml +++ b/src/tools/jsondocck/Cargo.toml @@ -10,4 +10,3 @@ regex = "1.4" shlex = "1.0" serde_json = "1.0" fs-err = "2.5.0" -once_cell = "1.0" diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs index e3d05ec83159..688b403bf0e0 100644 --- a/src/tools/jsondocck/src/main.rs +++ b/src/tools/jsondocck/src/main.rs @@ -1,8 +1,8 @@ use jsonpath_lib::select; -use once_cell::sync::Lazy; use regex::{Regex, RegexBuilder}; use serde_json::Value; use std::borrow::Cow; +use std::sync::OnceLock; use std::{env, fmt, fs}; mod cache; @@ -95,7 +95,8 @@ impl fmt::Display for CommandKind { } } -static LINE_PATTERN: Lazy = Lazy::new(|| { +static LINE_PATTERN: OnceLock = OnceLock::new(); +fn line_pattern() -> Regex { RegexBuilder::new( r#" \s(?P!?)@(?P!?) @@ -107,7 +108,7 @@ static LINE_PATTERN: Lazy = Lazy::new(|| { .unicode(true) .build() .unwrap() -}); +} fn print_err(msg: &str, lineno: usize) { eprintln!("Invalid command: {} on line {}", msg, lineno) @@ -123,7 +124,7 @@ fn get_commands(template: &str) -> Result, ()> { for (lineno, line) in file.split('\n').enumerate() { let lineno = lineno + 1; - let cap = match LINE_PATTERN.captures(line) { + let cap = match LINE_PATTERN.get_or_init(line_pattern).captures(line) { Some(c) => c, None => continue, }; diff --git a/src/tools/linkchecker/Cargo.toml b/src/tools/linkchecker/Cargo.toml index 318a69ab8359..05049aabc7d9 100644 --- a/src/tools/linkchecker/Cargo.toml +++ b/src/tools/linkchecker/Cargo.toml @@ -9,5 +9,4 @@ path = "main.rs" [dependencies] regex = "1" -once_cell = "1" html5ever = "0.26.0" diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index f49c6e79f13c..32f935de7302 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -18,8 +18,6 @@ use html5ever::tendril::ByteTendril; use html5ever::tokenizer::{ BufferQueue, TagToken, Token, TokenSink, TokenSinkResult, Tokenizer, TokenizerOpts, }; -use once_cell::sync::Lazy; -use regex::Regex; use std::cell::RefCell; use std::collections::{HashMap, HashSet}; use std::env; @@ -69,8 +67,12 @@ const INTRA_DOC_LINK_EXCEPTIONS: &[(&str, &[&str])] = &[ ]; -static BROKEN_INTRA_DOC_LINK: Lazy = - Lazy::new(|| Regex::new(r#"\[(.*)\]"#).unwrap()); +macro_rules! static_regex { + ($re:literal) => {{ + static RE: ::std::sync::OnceLock<::regex::Regex> = ::std::sync::OnceLock::new(); + RE.get_or_init(|| ::regex::Regex::new($re).unwrap()) + }}; +} macro_rules! t { ($e:expr) => { @@ -373,7 +375,7 @@ impl Checker { // Search for intra-doc links that rustdoc didn't warn about // NOTE: only looks at one line at a time; in practice this should find most links for (i, line) in source.lines().enumerate() { - for broken_link in BROKEN_INTRA_DOC_LINK.captures_iter(line) { + for broken_link in static_regex!(r#"\[(.*)\]"#).captures_iter(line) { if is_intra_doc_exception(file, &broken_link[1]) { report.intra_doc_exceptions += 1; } else { diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index b00dae784d22..ac8b4b37e920 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -46,7 +46,6 @@ colored = "2" ui_test = "0.21.1" rustc_version = "0.4" regex = "1.5.5" -lazy_static = "1.4.0" tempfile = "3" [package.metadata.rust-analyzer] diff --git a/src/tools/miri/tests/ui.rs b/src/tools/miri/tests/ui.rs index ace0da012536..efeefbe29fbc 100644 --- a/src/tools/miri/tests/ui.rs +++ b/src/tools/miri/tests/ui.rs @@ -1,6 +1,7 @@ use std::ffi::OsString; use std::num::NonZeroUsize; use std::path::{Path, PathBuf}; +use std::sync::OnceLock; use std::{env, process::Command}; use colored::*; @@ -67,8 +68,8 @@ fn miri_config(target: &str, path: &str, mode: Mode, with_dependencies: bool) -> let mut config = Config { target: Some(target.to_owned()), - stderr_filters: STDERR.clone(), - stdout_filters: STDOUT.clone(), + stderr_filters: stderr_filters().into(), + stdout_filters: stdout_filters().into(), mode, program, out_dir: PathBuf::from(std::env::var_os("CARGO_TARGET_DIR").unwrap()).join("ui"), @@ -174,15 +175,18 @@ fn run_tests( } macro_rules! regexes { - ($name:ident: $($regex:expr => $replacement:expr,)*) => {lazy_static::lazy_static! { - static ref $name: Vec<(Match, &'static [u8])> = vec![ - $((Regex::new($regex).unwrap().into(), $replacement.as_bytes()),)* - ]; - }}; + ($name:ident: $($regex:expr => $replacement:expr,)*) => { + fn $name() -> &'static [(Match, &'static [u8])] { + static S: OnceLock> = OnceLock::new(); + S.get_or_init(|| vec![ + $((Regex::new($regex).unwrap().into(), $replacement.as_bytes()),)* + ]) + } + }; } regexes! { - STDOUT: + stdout_filters: // Windows file paths r"\\" => "/", // erase borrow tags @@ -191,7 +195,7 @@ regexes! { } regexes! { - STDERR: + stderr_filters: // erase line and column info r"\.rs:[0-9]+:[0-9]+(: [0-9]+:[0-9]+)?" => ".rs:LL:CC", // erase alloc ids diff --git a/src/tools/rustfmt/Cargo.toml b/src/tools/rustfmt/Cargo.toml index 032b9b548104..b18c80654a07 100644 --- a/src/tools/rustfmt/Cargo.toml +++ b/src/tools/rustfmt/Cargo.toml @@ -44,7 +44,6 @@ dirs = "4.0" getopts = "0.2" ignore = "0.4" itertools = "0.11" -lazy_static = "1.4" regex = "1.7" serde = { version = "1.0.160", features = ["derive"] } serde_json = "1.0" diff --git a/src/tools/rustfmt/src/comment.rs b/src/tools/rustfmt/src/comment.rs index 7d1b0384431b..099e12f86dd2 100644 --- a/src/tools/rustfmt/src/comment.rs +++ b/src/tools/rustfmt/src/comment.rs @@ -3,8 +3,6 @@ use std::{borrow::Cow, iter}; use itertools::{multipeek, MultiPeek}; -use lazy_static::lazy_static; -use regex::Regex; use rustc_span::Span; use crate::config::Config; @@ -17,17 +15,6 @@ use crate::utils::{ }; use crate::{ErrorKind, FormattingError}; -lazy_static! { - /// A regex matching reference doc links. - /// - /// ```markdown - /// /// An [example]. - /// /// - /// /// [example]: this::is::a::link - /// ``` - static ref REFERENCE_LINK_URL: Regex = Regex::new(r"^\[.+\]\s?:").unwrap(); -} - fn is_custom_comment(comment: &str) -> bool { if !comment.starts_with("//") { false @@ -980,11 +967,16 @@ fn trim_custom_comment_prefix(s: &str) -> String { /// Returns `true` if the given string MAY include URLs or alike. fn has_url(s: &str) -> bool { // This function may return false positive, but should get its job done in most cases. + // The regex is indended to capture text such as the below. + // + // /// An [example]. + // /// + // /// [example]: this::is::a::link s.contains("https://") || s.contains("http://") || s.contains("ftp://") || s.contains("file://") - || REFERENCE_LINK_URL.is_match(s) + || static_regex!(r"^\[.+\]\s?:").is_match(s) } /// Returns true if the given string may be part of a Markdown table. diff --git a/src/tools/rustfmt/src/lib.rs b/src/tools/rustfmt/src/lib.rs index 877d057a34ba..e07720f30ca5 100644 --- a/src/tools/rustfmt/src/lib.rs +++ b/src/tools/rustfmt/src/lib.rs @@ -5,9 +5,6 @@ #![allow(clippy::match_like_matches_macro)] #![allow(unreachable_pub)] -#[cfg(test)] -#[macro_use] -extern crate lazy_static; #[macro_use] extern crate tracing; @@ -62,6 +59,13 @@ pub use crate::rustfmt_diff::{ModifiedChunk, ModifiedLines}; #[macro_use] mod utils; +macro_rules! static_regex { + ($re:literal) => {{ + static RE: ::std::sync::OnceLock<::regex::Regex> = ::std::sync::OnceLock::new(); + RE.get_or_init(|| ::regex::Regex::new($re).unwrap()) + }}; +} + mod attr; mod chains; mod closures; diff --git a/src/tools/rustfmt/src/test/configuration_snippet.rs b/src/tools/rustfmt/src/test/configuration_snippet.rs index 80b61c88a001..a195b306da38 100644 --- a/src/tools/rustfmt/src/test/configuration_snippet.rs +++ b/src/tools/rustfmt/src/test/configuration_snippet.rs @@ -24,19 +24,6 @@ impl ConfigurationSection { fn get_section>( file: &mut Enumerate, ) -> Option { - lazy_static! { - static ref CONFIG_NAME_REGEX: regex::Regex = - regex::Regex::new(r"^## `([^`]+)`").expect("failed creating configuration pattern"); - // Configuration values, which will be passed to `from_str`: - // - // - must be prefixed with `####` - // - must be wrapped in backticks - // - may by wrapped in double quotes (which will be stripped) - static ref CONFIG_VALUE_REGEX: regex::Regex = - regex::Regex::new(r#"^#### `"?([^`]+?)"?`"#) - .expect("failed creating configuration value pattern"); - } - loop { match file.next() { Some((i, line)) => { @@ -53,9 +40,14 @@ impl ConfigurationSection { let start_line = (i + 2) as u32; return Some(ConfigurationSection::CodeBlock((block, start_line))); - } else if let Some(c) = CONFIG_NAME_REGEX.captures(&line) { + } else if let Some(c) = static_regex!(r"^## `([^`]+)`").captures(&line) { return Some(ConfigurationSection::ConfigName(String::from(&c[1]))); - } else if let Some(c) = CONFIG_VALUE_REGEX.captures(&line) { + } else if let Some(c) = static_regex!(r#"^#### `"?([^`]+?)"?`"#).captures(&line) { + // Configuration values, which will be passed to `from_str` + // + // - must be prefixed with `####` + // - must be wrapped in backticks + // - may by wrapped in double quotes (which will be stripped) return Some(ConfigurationSection::ConfigValue(String::from(&c[1]))); } } diff --git a/src/tools/suggest-tests/Cargo.toml b/src/tools/suggest-tests/Cargo.toml index f4f4d548bb79..7c048d53a505 100644 --- a/src/tools/suggest-tests/Cargo.toml +++ b/src/tools/suggest-tests/Cargo.toml @@ -6,4 +6,3 @@ edition = "2021" [dependencies] glob = "0.3.0" build_helper = { version = "0.1.0", path = "../build_helper" } -once_cell = "1.17.1" diff --git a/src/tools/suggest-tests/src/lib.rs b/src/tools/suggest-tests/src/lib.rs index 1c1d9d0333dd..8932403ac9fd 100644 --- a/src/tools/suggest-tests/src/lib.rs +++ b/src/tools/suggest-tests/src/lib.rs @@ -5,7 +5,7 @@ use std::{ use dynamic_suggestions::DYNAMIC_SUGGESTIONS; use glob::Pattern; -use static_suggestions::STATIC_SUGGESTIONS; +use static_suggestions::static_suggestions; mod dynamic_suggestions; mod static_suggestions; @@ -33,7 +33,7 @@ pub fn get_suggestions>(modified_files: &[T]) -> Vec { let mut suggestions = Vec::new(); // static suggestions - for (globs, sugs) in STATIC_SUGGESTIONS.iter() { + for (globs, sugs) in static_suggestions().iter() { let globs = globs .iter() .map(|glob| Pattern::new(glob).expect("Found invalid glob pattern!")) diff --git a/src/tools/suggest-tests/src/static_suggestions.rs b/src/tools/suggest-tests/src/static_suggestions.rs index fbd265ea42a2..a34a4b16ec1b 100644 --- a/src/tools/suggest-tests/src/static_suggestions.rs +++ b/src/tools/suggest-tests/src/static_suggestions.rs @@ -1,10 +1,14 @@ use crate::{sug, Suggestion}; +use std::sync::OnceLock; // FIXME: perhaps this could use `std::lazy` when it is stablizied macro_rules! static_suggestions { ($( [ $( $glob:expr ),* $(,)? ] => [ $( $suggestion:expr ),* $(,)? ] ),* $(,)? ) => { - pub(crate) const STATIC_SUGGESTIONS: ::once_cell::unsync::Lazy, Vec)>> - = ::once_cell::unsync::Lazy::new(|| vec![ $( (vec![ $($glob),* ], vec![ $($suggestion),* ]) ),*]); + pub(crate) fn static_suggestions() -> &'static [(Vec<&'static str>, Vec)] + { + static S: OnceLock, Vec)>> = OnceLock::new(); + S.get_or_init(|| vec![ $( (vec![ $($glob),* ], vec![ $($suggestion),* ]) ),*]) + } } } diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index 96866e742488..63963b0bd1ce 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -8,7 +8,6 @@ autobins = false cargo_metadata = "0.15" regex = "1" miropt-test-tools = { path = "../miropt-test-tools" } -lazy_static = "1" walkdir = "2" ignore = "0.4.18" semver = "1.0" diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index d673ce7a736d..3e84bf3c34be 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -17,8 +17,6 @@ use std::fs; use std::num::NonZeroU32; use std::path::{Path, PathBuf}; -use regex::Regex; - #[cfg(test)] mod tests; @@ -251,16 +249,10 @@ fn format_features<'a>( } fn find_attr_val<'a>(line: &'a str, attr: &str) -> Option<&'a str> { - lazy_static::lazy_static! { - static ref ISSUE: Regex = Regex::new(r#"issue\s*=\s*"([^"]*)""#).unwrap(); - static ref FEATURE: Regex = Regex::new(r#"feature\s*=\s*"([^"]*)""#).unwrap(); - static ref SINCE: Regex = Regex::new(r#"since\s*=\s*"([^"]*)""#).unwrap(); - } - let r = match attr { - "issue" => &*ISSUE, - "feature" => &*FEATURE, - "since" => &*SINCE, + "issue" => static_regex!(r#"issue\s*=\s*"([^"]*)""#), + "feature" => static_regex!(r#"feature\s*=\s*"([^"]*)""#), + "since" => static_regex!(r#"since\s*=\s*"([^"]*)""#), _ => unimplemented!("{attr} not handled"), }; @@ -528,11 +520,8 @@ fn map_lib_features( }}; } - lazy_static::lazy_static! { - static ref COMMENT_LINE: Regex = Regex::new(r"^\s*//").unwrap(); - } // exclude commented out lines - if COMMENT_LINE.is_match(line) { + if static_regex!(r"^\s*//").is_match(line) { continue; } diff --git a/src/tools/tidy/src/fluent_alphabetical.rs b/src/tools/tidy/src/fluent_alphabetical.rs index 9803b6eab2db..a85367984dee 100644 --- a/src/tools/tidy/src/fluent_alphabetical.rs +++ b/src/tools/tidy/src/fluent_alphabetical.rs @@ -6,8 +6,8 @@ use std::{fs::OpenOptions, io::Write, path::Path}; use regex::Regex; -lazy_static::lazy_static! { - static ref MESSAGE: Regex = Regex::new(r#"(?m)^([a-zA-Z0-9_]+)\s*=\s*"#).unwrap(); +fn message() -> &'static Regex { + static_regex!(r#"(?m)^([a-zA-Z0-9_]+)\s*=\s*"#) } fn filter_fluent(path: &Path) -> bool { @@ -20,7 +20,7 @@ fn check_alphabetic( bad: &mut bool, all_defined_msgs: &mut HashMap, ) { - let mut matches = MESSAGE.captures_iter(fluent).peekable(); + let mut matches = message().captures_iter(fluent).peekable(); while let Some(m) = matches.next() { let name = m.get(1).unwrap(); if let Some(defined_filename) = all_defined_msgs.get(name.as_str()) { @@ -60,7 +60,7 @@ fn sort_messages( let mut chunks = vec![]; let mut cur = String::new(); for line in fluent.lines() { - if let Some(name) = MESSAGE.find(line) { + if let Some(name) = message().find(line) { if let Some(defined_filename) = all_defined_msgs.get(name.as_str()) { tidy_error!( bad, diff --git a/src/tools/tidy/src/fluent_used.rs b/src/tools/tidy/src/fluent_used.rs index b73e79cb38d9..8b6c6c18813d 100644 --- a/src/tools/tidy/src/fluent_used.rs +++ b/src/tools/tidy/src/fluent_used.rs @@ -1,14 +1,9 @@ //! Checks that all Fluent messages appear at least twice use crate::walk::{filter_dirs, walk}; -use regex::Regex; use std::collections::HashMap; use std::path::Path; -lazy_static::lazy_static! { - static ref WORD: Regex = Regex::new(r"\w+").unwrap(); -} - fn filter_used_messages( contents: &str, msgs_not_appeared_yet: &mut HashMap, @@ -17,7 +12,7 @@ fn filter_used_messages( // we don't just check messages never appear in Rust files, // because messages can be used as parts of other fluent messages in Fluent files, // so we do checking messages appear only once in all Rust and Fluent files. - let mut matches = WORD.find_iter(contents); + let mut matches = static_regex!(r"\w+").find_iter(contents); while let Some(name) = matches.next() { if let Some((name, filename)) = msgs_not_appeared_yet.remove_entry(name.as_str()) { // if one msg appears for the first time, diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 23f303276aa2..c15081a56d1a 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -5,6 +5,13 @@ use termcolor::WriteColor; +macro_rules! static_regex { + ($re:literal) => {{ + static RE: ::std::sync::OnceLock<::regex::Regex> = ::std::sync::OnceLock::new(); + RE.get_or_init(|| ::regex::Regex::new($re).unwrap()) + }}; +} + /// A helper macro to `unwrap` a result except also print out details like: /// /// * The expression that failed diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index a1445ce5896b..6b664f02b53b 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -18,7 +18,7 @@ // ignore-tidy-dbg use crate::walk::{filter_dirs, walk}; -use regex::{Regex, RegexSet}; +use regex::RegexSet; use rustc_hash::FxHashMap; use std::{ffi::OsStr, path::Path}; @@ -178,20 +178,14 @@ fn should_ignore(line: &str) -> bool { // Matches test annotations like `//~ ERROR text`. // This mirrors the regex in src/tools/compiletest/src/runtest.rs, please // update both if either are changed. - lazy_static::lazy_static! { - static ref ANNOTATION_RE: Regex = Regex::new("\\s*//(\\[.*\\])?~.*").unwrap(); - } + static_regex!("\\s*//(\\[.*\\])?~.*").is_match(line) + || ANNOTATIONS_TO_IGNORE.iter().any(|a| line.contains(a)) + // For `ui_test`-style UI test directives, also ignore // - `//@[rev] compile-flags` // - `//@[rev] normalize-stderr-test` - lazy_static::lazy_static! { - static ref UI_TEST_LONG_DIRECTIVES_RE: Regex = - Regex::new("\\s*//@(\\[.*\\]) (compile-flags|normalize-stderr-test|error-pattern).*") - .unwrap(); - } - ANNOTATION_RE.is_match(line) - || ANNOTATIONS_TO_IGNORE.iter().any(|a| line.contains(a)) - || UI_TEST_LONG_DIRECTIVES_RE.is_match(line) + || static_regex!("\\s*//@(\\[.*\\]) (compile-flags|normalize-stderr-test|error-pattern).*") + .is_match(line) } /// Returns `true` if `line` is allowed to be longer than the normal limit. diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index f9985a757030..94a0eee154d9 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -2,8 +2,6 @@ //! - the number of entries in each directory must be less than `ENTRY_LIMIT` //! - there are no stray `.stderr` files use ignore::Walk; -use lazy_static::lazy_static; -use regex::Regex; use std::collections::{BTreeSet, HashMap}; use std::ffi::OsStr; use std::fs; @@ -182,12 +180,8 @@ pub fn check(root_path: &Path, bless: bool, bad: &mut bool) { } if ext == "rs" { - lazy_static! { - static ref ISSUE_NAME_REGEX: Regex = - Regex::new(r"^issues?[-_]?(\d{3,})").unwrap(); - } - - if let Some(test_name) = ISSUE_NAME_REGEX.captures(testname) { + if let Some(test_name) = static_regex!(r"^issues?[-_]?(\d{3,})").captures(testname) + { // these paths are always relative to the passed `path` and always UTF8 let stripped_path = file_path .strip_prefix(path) From 0b1f09e6f7c8228b566f035d95b4f2b742e3d0cb Mon Sep 17 00:00:00 2001 From: Mats Macke <61540264+MATSMACKE@users.noreply.github.com> Date: Sat, 27 Apr 2024 19:54:24 +0200 Subject: [PATCH 120/279] Fixed reduction of & in cast_possible_truncation Fixed formatting Added tests for issue #12721 Checking for reduction on RHS --- .../src/casts/cast_possible_truncation.rs | 7 +- tests/ui/cast.rs | 21 +- tests/ui/cast.stderr | 206 ++++++++++-------- 3 files changed, 141 insertions(+), 93 deletions(-) diff --git a/clippy_lints/src/casts/cast_possible_truncation.rs b/clippy_lints/src/casts/cast_possible_truncation.rs index dbfa8e1ee91b..7c5acd1a678d 100644 --- a/clippy_lints/src/casts/cast_possible_truncation.rs +++ b/clippy_lints/src/casts/cast_possible_truncation.rs @@ -40,9 +40,14 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b get_constant_bits(cx, right).map_or(0, |b| b.saturating_sub(1)) }) }, - BinOpKind::Rem | BinOpKind::BitAnd => get_constant_bits(cx, right) + BinOpKind::Rem => get_constant_bits(cx, right) .unwrap_or(u64::MAX) .min(apply_reductions(cx, nbits, left, signed)), + BinOpKind::BitAnd => get_constant_bits(cx, right) + .unwrap_or(u64::MAX) + .min(get_constant_bits(cx, left).unwrap_or(u64::MAX)) + .min(apply_reductions(cx, nbits, right, signed)) + .min(apply_reductions(cx, nbits, left, signed)), BinOpKind::Shr => apply_reductions(cx, nbits, left, signed) .saturating_sub(constant_int(cx, right).map_or(0, |s| u64::try_from(s).unwrap_or_default())), _ => nbits, diff --git a/tests/ui/cast.rs b/tests/ui/cast.rs index 215c008902d2..453d62ce6075 100644 --- a/tests/ui/cast.rs +++ b/tests/ui/cast.rs @@ -13,7 +13,8 @@ clippy::cast_abs_to_unsigned, clippy::no_effect, clippy::unnecessary_operation, - clippy::unnecessary_literal_unwrap + clippy::unnecessary_literal_unwrap, + clippy::identity_op )] fn main() { @@ -479,3 +480,21 @@ fn issue12506() -> usize { let bar: Result, u32> = Ok(Some(10)); bar.unwrap().unwrap() as usize } + +fn issue12721() { + fn x() -> u64 { + u64::MAX + } + + // Don't lint. + (255 & 999999u64) as u8; + // Don't lint. + let _ = ((x() & 255) & 999999) as u8; + // Don't lint. + let _ = (999999 & (x() & 255)) as u8; + + (256 & 999999u64) as u8; + //~^ ERROR: casting `u64` to `u8` may truncate the value + (255 % 999999u64) as u8; + //~^ ERROR: casting `u64` to `u8` may truncate the value +} diff --git a/tests/ui/cast.stderr b/tests/ui/cast.stderr index 8b269c471765..43c0d8f4ed73 100644 --- a/tests/ui/cast.stderr +++ b/tests/ui/cast.stderr @@ -1,5 +1,5 @@ error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:22:5 + --> tests/ui/cast.rs:23:5 | LL | x0 as f32; | ^^^^^^^^^ @@ -8,37 +8,37 @@ LL | x0 as f32; = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` error: casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:26:5 + --> tests/ui/cast.rs:27:5 | LL | x1 as f32; | ^^^^^^^^^ error: casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast.rs:28:5 + --> tests/ui/cast.rs:29:5 | LL | x1 as f64; | ^^^^^^^^^ error: casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:31:5 + --> tests/ui/cast.rs:32:5 | LL | x2 as f32; | ^^^^^^^^^ error: casting `u64` to `f32` causes a loss of precision (`u64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:34:5 + --> tests/ui/cast.rs:35:5 | LL | x3 as f32; | ^^^^^^^^^ error: casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast.rs:36:5 + --> tests/ui/cast.rs:37:5 | LL | x3 as f64; | ^^^^^^^^^ error: casting `f32` to `i32` may truncate the value - --> tests/ui/cast.rs:39:5 + --> tests/ui/cast.rs:40:5 | LL | 1f32 as i32; | ^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL | 1f32 as i32; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]` error: casting `f32` to `u32` may truncate the value - --> tests/ui/cast.rs:41:5 + --> tests/ui/cast.rs:42:5 | LL | 1f32 as u32; | ^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | 1f32 as u32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:41:5 + --> tests/ui/cast.rs:42:5 | LL | 1f32 as u32; | ^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | 1f32 as u32; = help: to override `-D warnings` add `#[allow(clippy::cast_sign_loss)]` error: casting `f64` to `f32` may truncate the value - --> tests/ui/cast.rs:45:5 + --> tests/ui/cast.rs:46:5 | LL | 1f64 as f32; | ^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | 1f64 as f32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `i32` to `i8` may truncate the value - --> tests/ui/cast.rs:47:5 + --> tests/ui/cast.rs:48:5 | LL | 1i32 as i8; | ^^^^^^^^^^ @@ -85,7 +85,7 @@ LL | i8::try_from(1i32); | ~~~~~~~~~~~~~~~~~~ error: casting `i32` to `u8` may truncate the value - --> tests/ui/cast.rs:49:5 + --> tests/ui/cast.rs:50:5 | LL | 1i32 as u8; | ^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | u8::try_from(1i32); | ~~~~~~~~~~~~~~~~~~ error: casting `f64` to `isize` may truncate the value - --> tests/ui/cast.rs:51:5 + --> tests/ui/cast.rs:52:5 | LL | 1f64 as isize; | ^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL | 1f64 as isize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `usize` may truncate the value - --> tests/ui/cast.rs:53:5 + --> tests/ui/cast.rs:54:5 | LL | 1f64 as usize; | ^^^^^^^^^^^^^ @@ -113,13 +113,13 @@ LL | 1f64 as usize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:53:5 + --> tests/ui/cast.rs:54:5 | LL | 1f64 as usize; | ^^^^^^^^^^^^^ error: casting `u32` to `u16` may truncate the value - --> tests/ui/cast.rs:56:5 + --> tests/ui/cast.rs:57:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^^^^^^^^ @@ -131,7 +131,7 @@ LL | u16::try_from(1f32 as u32); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `f32` to `u32` may truncate the value - --> tests/ui/cast.rs:56:5 + --> tests/ui/cast.rs:57:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^ @@ -139,13 +139,13 @@ LL | 1f32 as u32 as u16; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:56:5 + --> tests/ui/cast.rs:57:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^ error: casting `i32` to `i8` may truncate the value - --> tests/ui/cast.rs:61:22 + --> tests/ui/cast.rs:62:22 | LL | let _x: i8 = 1i32 as _; | ^^^^^^^^^ @@ -157,7 +157,7 @@ LL | let _x: i8 = 1i32.try_into(); | ~~~~~~~~~~~~~~~ error: casting `f32` to `i32` may truncate the value - --> tests/ui/cast.rs:63:9 + --> tests/ui/cast.rs:64:9 | LL | 1f32 as i32; | ^^^^^^^^^^^ @@ -165,7 +165,7 @@ LL | 1f32 as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `i32` may truncate the value - --> tests/ui/cast.rs:65:9 + --> tests/ui/cast.rs:66:9 | LL | 1f64 as i32; | ^^^^^^^^^^^ @@ -173,7 +173,7 @@ LL | 1f64 as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u8` may truncate the value - --> tests/ui/cast.rs:67:9 + --> tests/ui/cast.rs:68:9 | LL | 1f32 as u8; | ^^^^^^^^^^ @@ -181,13 +181,13 @@ LL | 1f32 as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u8` may lose the sign of the value - --> tests/ui/cast.rs:67:9 + --> tests/ui/cast.rs:68:9 | LL | 1f32 as u8; | ^^^^^^^^^^ error: casting `u8` to `i8` may wrap around the value - --> tests/ui/cast.rs:72:5 + --> tests/ui/cast.rs:73:5 | LL | 1u8 as i8; | ^^^^^^^^^ @@ -196,31 +196,31 @@ LL | 1u8 as i8; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]` error: casting `u16` to `i16` may wrap around the value - --> tests/ui/cast.rs:75:5 + --> tests/ui/cast.rs:76:5 | LL | 1u16 as i16; | ^^^^^^^^^^^ error: casting `u32` to `i32` may wrap around the value - --> tests/ui/cast.rs:77:5 + --> tests/ui/cast.rs:78:5 | LL | 1u32 as i32; | ^^^^^^^^^^^ error: casting `u64` to `i64` may wrap around the value - --> tests/ui/cast.rs:79:5 + --> tests/ui/cast.rs:80:5 | LL | 1u64 as i64; | ^^^^^^^^^^^ error: casting `usize` to `isize` may wrap around the value - --> tests/ui/cast.rs:81:5 + --> tests/ui/cast.rs:82:5 | LL | 1usize as isize; | ^^^^^^^^^^^^^^^ error: casting `usize` to `i8` may truncate the value - --> tests/ui/cast.rs:84:5 + --> tests/ui/cast.rs:85:5 | LL | 1usize as i8; | ^^^^^^^^^^^^ @@ -232,7 +232,7 @@ LL | i8::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i16` may truncate the value - --> tests/ui/cast.rs:87:5 + --> tests/ui/cast.rs:88:5 | LL | 1usize as i16; | ^^^^^^^^^^^^^ @@ -244,7 +244,7 @@ LL | i16::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i16` may wrap around the value on targets with 16-bit wide pointers - --> tests/ui/cast.rs:87:5 + --> tests/ui/cast.rs:88:5 | LL | 1usize as i16; | ^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | 1usize as i16; = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:92:5 + --> tests/ui/cast.rs:93:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ @@ -265,19 +265,19 @@ LL | i32::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:92:5 + --> tests/ui/cast.rs:93:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ error: casting `usize` to `i64` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:96:5 + --> tests/ui/cast.rs:97:5 | LL | 1usize as i64; | ^^^^^^^^^^^^^ error: casting `u16` to `isize` may wrap around the value on targets with 16-bit wide pointers - --> tests/ui/cast.rs:101:5 + --> tests/ui/cast.rs:102:5 | LL | 1u16 as isize; | ^^^^^^^^^^^^^ @@ -286,13 +286,13 @@ LL | 1u16 as isize; = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:105:5 + --> tests/ui/cast.rs:106:5 | LL | 1u32 as isize; | ^^^^^^^^^^^^^ error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:108:5 + --> tests/ui/cast.rs:109:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ @@ -304,55 +304,55 @@ LL | isize::try_from(1u64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:108:5 + --> tests/ui/cast.rs:109:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:113:5 + --> tests/ui/cast.rs:114:5 | LL | -1i32 as u32; | ^^^^^^^^^^^^ error: casting `isize` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:116:5 + --> tests/ui/cast.rs:117:5 | LL | -1isize as usize; | ^^^^^^^^^^^^^^^^ error: casting `i8` to `u8` may lose the sign of the value - --> tests/ui/cast.rs:127:5 + --> tests/ui/cast.rs:128:5 | LL | (i8::MIN).abs() as u8; | ^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:131:5 + --> tests/ui/cast.rs:132:5 | LL | (-1i64).abs() as u64; | ^^^^^^^^^^^^^^^^^^^^ error: casting `isize` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:132:5 + --> tests/ui/cast.rs:133:5 | LL | (-1isize).abs() as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:139:5 + --> tests/ui/cast.rs:140:5 | LL | (unsafe { (-1i64).checked_abs().unwrap_unchecked() }) as u64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:154:5 + --> tests/ui/cast.rs:155:5 | LL | (unsafe { (-1i64).checked_isqrt().unwrap_unchecked() }) as u64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `i8` may truncate the value - --> tests/ui/cast.rs:205:5 + --> tests/ui/cast.rs:206:5 | LL | (-99999999999i64).min(1) as i8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -364,7 +364,7 @@ LL | i8::try_from((-99999999999i64).min(1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:219:5 + --> tests/ui/cast.rs:220:5 | LL | 999999u64.clamp(0, 256) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -376,7 +376,7 @@ LL | u8::try_from(999999u64.clamp(0, 256)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E2` to `u8` may truncate the value - --> tests/ui/cast.rs:242:21 + --> tests/ui/cast.rs:243:21 | LL | let _ = self as u8; | ^^^^^^^^^^ @@ -388,7 +388,7 @@ LL | let _ = u8::try_from(self); | ~~~~~~~~~~~~~~~~~~ error: casting `main::E2::B` to `u8` will truncate the value - --> tests/ui/cast.rs:244:21 + --> tests/ui/cast.rs:245:21 | LL | let _ = Self::B as u8; | ^^^^^^^^^^^^^ @@ -397,7 +397,7 @@ LL | let _ = Self::B as u8; = help: to override `-D warnings` add `#[allow(clippy::cast_enum_truncation)]` error: casting `main::E5` to `i8` may truncate the value - --> tests/ui/cast.rs:286:21 + --> tests/ui/cast.rs:287:21 | LL | let _ = self as i8; | ^^^^^^^^^^ @@ -409,13 +409,13 @@ LL | let _ = i8::try_from(self); | ~~~~~~~~~~~~~~~~~~ error: casting `main::E5::A` to `i8` will truncate the value - --> tests/ui/cast.rs:288:21 + --> tests/ui/cast.rs:289:21 | LL | let _ = Self::A as i8; | ^^^^^^^^^^^^^ error: casting `main::E6` to `i16` may truncate the value - --> tests/ui/cast.rs:305:21 + --> tests/ui/cast.rs:306:21 | LL | let _ = self as i16; | ^^^^^^^^^^^ @@ -427,7 +427,7 @@ LL | let _ = i16::try_from(self); | ~~~~~~~~~~~~~~~~~~~ error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:324:21 + --> tests/ui/cast.rs:325:21 | LL | let _ = self as usize; | ^^^^^^^^^^^^^ @@ -439,7 +439,7 @@ LL | let _ = usize::try_from(self); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E10` to `u16` may truncate the value - --> tests/ui/cast.rs:371:21 + --> tests/ui/cast.rs:372:21 | LL | let _ = self as u16; | ^^^^^^^^^^^ @@ -451,7 +451,7 @@ LL | let _ = u16::try_from(self); | ~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:382:13 + --> tests/ui/cast.rs:383:13 | LL | let c = (q >> 16) as u8; | ^^^^^^^^^^^^^^^ @@ -463,7 +463,7 @@ LL | let c = u8::try_from(q >> 16); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:386:13 + --> tests/ui/cast.rs:387:13 | LL | let c = (q / 1000) as u8; | ^^^^^^^^^^^^^^^^ @@ -475,85 +475,85 @@ LL | let c = u8::try_from(q / 1000); | ~~~~~~~~~~~~~~~~~~~~~~ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:398:9 + --> tests/ui/cast.rs:399:9 | LL | (x * x) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:403:32 + --> tests/ui/cast.rs:404:32 | LL | let _a = |x: i32| -> u32 { (x * x * x * x) as u32 }; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:405:5 + --> tests/ui/cast.rs:406:5 | LL | (2_i32).checked_pow(3).unwrap() as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:406:5 + --> tests/ui/cast.rs:407:5 | LL | (-2_i32).pow(3) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:411:5 + --> tests/ui/cast.rs:412:5 | LL | (-5_i32 % 2) as u32; | ^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:413:5 + --> tests/ui/cast.rs:414:5 | LL | (-5_i32 % -2) as u32; | ^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:416:5 + --> tests/ui/cast.rs:417:5 | LL | (-2_i32 >> 1) as u32; | ^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:420:5 + --> tests/ui/cast.rs:421:5 | LL | (x * x) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:421:5 + --> tests/ui/cast.rs:422:5 | LL | (x * x * x) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:425:5 + --> tests/ui/cast.rs:426:5 | LL | (y * y * y * y * -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:427:5 + --> tests/ui/cast.rs:428:5 | LL | (y * y * y / y * 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:428:5 + --> tests/ui/cast.rs:429:5 | LL | (y * y / y * 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:430:5 + --> tests/ui/cast.rs:431:5 | LL | (y / y * y * -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `/` - --> tests/ui/cast.rs:430:6 + --> tests/ui/cast.rs:431:6 | LL | (y / y * y * -2) as u16; | ^^^^^ @@ -561,97 +561,97 @@ LL | (y / y * y * -2) as u16; = note: `#[deny(clippy::eq_op)]` on by default error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:433:5 + --> tests/ui/cast.rs:434:5 | LL | (y + y + y + -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:435:5 + --> tests/ui/cast.rs:436:5 | LL | (y + y + y + 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:439:5 + --> tests/ui/cast.rs:440:5 | LL | (z + -2) as u16; | ^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:441:5 + --> tests/ui/cast.rs:442:5 | LL | (z + z + 2) as u16; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:444:9 + --> tests/ui/cast.rs:445:9 | LL | (a * a * b * b * c * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:445:9 + --> tests/ui/cast.rs:446:9 | LL | (a * b * c) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:447:9 + --> tests/ui/cast.rs:448:9 | LL | (a * -b * c) as u32; | ^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:449:9 + --> tests/ui/cast.rs:450:9 | LL | (a * b * c * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:450:9 + --> tests/ui/cast.rs:451:9 | LL | (a * -2) as u32; | ^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:452:9 + --> tests/ui/cast.rs:453:9 | LL | (a * b * c * -2) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:454:9 + --> tests/ui/cast.rs:455:9 | LL | (a / b) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:455:9 + --> tests/ui/cast.rs:456:9 | LL | (a / b * c) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:457:9 + --> tests/ui/cast.rs:458:9 | LL | (a / b + b * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:459:9 + --> tests/ui/cast.rs:460:9 | LL | a.saturating_pow(3) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:461:9 + --> tests/ui/cast.rs:462:9 | LL | (a.abs() * b.pow(2) / c.abs()) as u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:469:21 + --> tests/ui/cast.rs:470:21 | LL | let _ = i32::MIN as u32; // cast_sign_loss | ^^^^^^^^^^^^^^^ @@ -662,7 +662,7 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:470:21 + --> tests/ui/cast.rs:471:21 | LL | let _ = u32::MAX as u8; // cast_possible_truncation | ^^^^^^^^^^^^^^ @@ -678,7 +678,7 @@ LL | let _ = u8::try_from(u32::MAX); // cast_possible_truncation | ~~~~~~~~~~~~~~~~~~~~~~ error: casting `f64` to `f32` may truncate the value - --> tests/ui/cast.rs:471:21 + --> tests/ui/cast.rs:472:21 | LL | let _ = std::f64::consts::PI as f32; // cast_possible_truncation | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -690,7 +690,7 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:480:5 + --> tests/ui/cast.rs:481:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -702,10 +702,34 @@ LL | usize::try_from(bar.unwrap().unwrap()) | error: casting `i64` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:480:5 + --> tests/ui/cast.rs:481:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 90 previous errors +error: casting `u64` to `u8` may truncate the value + --> tests/ui/cast.rs:496:5 + | +LL | (256 & 999999u64) as u8; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | u8::try_from(256 & 999999u64); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: casting `u64` to `u8` may truncate the value + --> tests/ui/cast.rs:498:5 + | +LL | (255 % 999999u64) as u8; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | u8::try_from(255 % 999999u64); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 92 previous errors From 607497d57caf28c3d06adfdd5bca826e9c81205b Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 28 Apr 2024 14:44:30 +0200 Subject: [PATCH 121/279] Port print-cfg run-make to Rust-based rmake.rs --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/print-cfg/Makefile | 37 ------- tests/run-make/print-cfg/rmake.rs | 100 ++++++++++++++++++ tests/run-make/print-to-output/rmake.rs | 67 ++++++++++++ 4 files changed, 167 insertions(+), 38 deletions(-) delete mode 100644 tests/run-make/print-cfg/Makefile create mode 100644 tests/run-make/print-cfg/rmake.rs create mode 100644 tests/run-make/print-to-output/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 1b560ee352c6..a2179b895b3d 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -219,7 +219,6 @@ run-make/prefer-rlib/Makefile run-make/pretty-print-to-file/Makefile run-make/pretty-print-with-dep-file/Makefile run-make/print-calling-conventions/Makefile -run-make/print-cfg/Makefile run-make/print-target-list/Makefile run-make/profile/Makefile run-make/prune-link-args/Makefile diff --git a/tests/run-make/print-cfg/Makefile b/tests/run-make/print-cfg/Makefile deleted file mode 100644 index 6b153e5b54ed..000000000000 --- a/tests/run-make/print-cfg/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# needs-llvm-components: x86 arm - -include ../tools.mk - -all: default output_to_file - $(RUSTC) --target x86_64-pc-windows-gnu --print cfg | $(CGREP) windows - $(RUSTC) --target x86_64-pc-windows-gnu --print cfg | $(CGREP) x86_64 - $(RUSTC) --target i686-pc-windows-msvc --print cfg | $(CGREP) msvc - $(RUSTC) --target i686-apple-darwin --print cfg | $(CGREP) macos - $(RUSTC) --target i686-unknown-linux-gnu --print cfg | $(CGREP) gnu - $(RUSTC) --target arm-unknown-linux-gnueabihf --print cfg | $(CGREP) target_abi= - $(RUSTC) --target arm-unknown-linux-gnueabihf --print cfg | $(CGREP) eabihf - -output_to_file: - # Backend-independent, printed by rustc_driver_impl/src/lib.rs - $(RUSTC) --target x86_64-pc-windows-gnu --print cfg=$(TMPDIR)/cfg.txt - $(CGREP) windows < $(TMPDIR)/cfg.txt - - # Printed from CodegenBackend trait impl in rustc_codegen_llvm/src/lib.rs - $(RUSTC) --print relocation-models=$(TMPDIR)/relocation-models.txt - $(CGREP) dynamic-no-pic < $(TMPDIR)/relocation-models.txt - - # Printed by compiler/rustc_codegen_llvm/src/llvm_util.rs - $(RUSTC) --target wasm32-unknown-unknown --print target-features=$(TMPDIR)/target-features.txt - $(CGREP) reference-types < $(TMPDIR)/target-features.txt - - # Printed by C++ code in rustc_llvm/llvm-wrapper/PassWrapper.cpp - $(RUSTC) --target wasm32-unknown-unknown --print target-cpus=$(TMPDIR)/target-cpus.txt - $(CGREP) generic < $(TMPDIR)/target-cpus.txt - -ifdef IS_WINDOWS -default: - $(RUSTC) --print cfg | $(CGREP) windows -else -default: - $(RUSTC) --print cfg | $(CGREP) unix -endif diff --git a/tests/run-make/print-cfg/rmake.rs b/tests/run-make/print-cfg/rmake.rs new file mode 100644 index 000000000000..0f829c9a95fc --- /dev/null +++ b/tests/run-make/print-cfg/rmake.rs @@ -0,0 +1,100 @@ +//! This checks the output of `--print=cfg` +//! +//! Specifically it checks that output is correctly formatted +//! (ie. no duplicated cfgs, values are between "", names are not). +//! +//! It also checks that some targets have the correct set cfgs. + +extern crate run_make_support; + +use std::collections::HashSet; +use std::ffi::OsString; +use std::io::BufRead; +use std::iter::FromIterator; + +use run_make_support::{rustc, tmp_dir}; + +fn main() { + check( + /*target*/ "x86_64-pc-windows-gnu", + /*includes*/ &["windows", "target_arch=\"x86_64\""], + /*disallow*/ &["unix"], + ); + check( + /*target*/ "i686-pc-windows-msvc", + /*includes*/ &["windows", "target_env=\"msvc\""], + /*disallow*/ &["unix"], + ); + check( + /*target*/ "i686-apple-darwin", + /*includes*/ &["unix", "target_os=\"macos\"", "target_vendor=\"apple\""], + /*disallow*/ &["windows"], + ); + check( + /*target*/ "i686-unknown-linux-gnu", + /*includes*/ &["unix", "target_env=\"gnu\""], + /*disallow*/ &["windows"], + ); + check( + /*target*/ "arm-unknown-linux-gnueabihf", + /*includes*/ &["unix", "target_abi=\"eabihf\""], + /*disallow*/ &["windows"], + ); +} + +fn check(target: &str, includes: &[&str], disallow: &[&str]) { + fn _inner(output: &str, includes: &[&str], disallow: &[&str]) { + let mut found = HashSet::::new(); + let mut recorded = HashSet::::new(); + + for l in output.lines() { + assert!(l == l.trim()); + if let Some((left, right)) = l.split_once('=') { + assert!(right.starts_with("\"")); + assert!(right.ends_with("\"")); + assert!(!left.contains("\"")); + } else { + assert!(!l.contains("\"")); + } + + assert!(recorded.insert(l.to_string()), "duplicated: {}", &l); + assert!(!disallow.contains(&l), "found disallowed: {}", &l); + if includes.contains(&l) { + assert!(found.insert(l.to_string()), "duplicated (includes): {}", &l); + } + } + + let should_found = HashSet::::from_iter(includes.iter().map(|s| s.to_string())); + let diff: Vec<_> = should_found.difference(&found).collect(); + + assert!( + diff.is_empty(), + "expected: {:?}, found: {:?} (~ {:?})", + &should_found, + &found, + &diff + ); + } + + // --print=cfg + { + let output = rustc().target(target).print("cfg").run(); + + let stdout = String::from_utf8(output.stdout).unwrap(); + + _inner(&stdout, includes, disallow); + } + + // --print=cfg=PATH + { + let tmp_path = tmp_dir().join(format!("{target}.cfg")); + let mut print_arg = OsString::from("--print=cfg="); + print_arg.push(tmp_path.as_os_str()); + + let output = rustc().target(target).arg(print_arg).run(); + + let output = std::fs::read_to_string(&tmp_path).unwrap(); + + _inner(&output, includes, disallow); + } +} diff --git a/tests/run-make/print-to-output/rmake.rs b/tests/run-make/print-to-output/rmake.rs new file mode 100644 index 000000000000..91724b492f8d --- /dev/null +++ b/tests/run-make/print-to-output/rmake.rs @@ -0,0 +1,67 @@ +//! This checks the output of some `--print` options when +//! output to a file (instead of stdout) + +extern crate run_make_support; + +use std::ffi::OsString; + +use run_make_support::{rustc, target, tmp_dir}; + +fn main() { + // Printed from CodegenBackend trait impl in rustc_codegen_llvm/src/lib.rs + check( + /*target*/ &target(), + /*option*/ "relocation-models", + /*includes*/ &["dynamic-no-pic"], + ); + + // Printed by compiler/rustc_codegen_llvm/src/llvm_util.rs + check( + /*target*/ "wasm32-unknown-unknown", + /*option*/ "target-features", + /*includes*/ &["reference-types"], + ); + + // Printed by C++ code in rustc_llvm/llvm-wrapper/PassWrapper.cpp + check( + /*target*/ "wasm32-unknown-unknown", + /*option*/ "target-cpus", + /*includes*/ &["generic"], + ); +} + +fn check(target: &str, option: &str, includes: &[&str]) { + fn _inner(output: &str, includes: &[&str]) { + for i in includes { + assert!(output.contains(i), "output doesn't contains: {}", i); + } + } + + // --print={option} + let stdout = { + let output = rustc().target(target).print(option).run(); + + let stdout = String::from_utf8(output.stdout).unwrap(); + + _inner(&stdout, includes); + + stdout + }; + + // --print={option}=PATH + let output = { + let tmp_path = tmp_dir().join(format!("{option}.txt")); + let mut print_arg = OsString::from(format!("--print={option}=")); + print_arg.push(tmp_path.as_os_str()); + + let _output = rustc().target(target).arg(print_arg).run(); + + let output = std::fs::read_to_string(&tmp_path).unwrap(); + + _inner(&output, includes); + + output + }; + + assert_eq!(&stdout, &output); +} From 006c94cfa1a4658318f237d87afb2a4434d42b39 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 28 Apr 2024 17:17:18 +0200 Subject: [PATCH 122/279] Use named struct arguments instead of comment named args --- tests/run-make/print-cfg/rmake.rs | 66 ++++++++++++---------- tests/run-make/print-to-output/rmake.rs | 75 +++++++++++++------------ 2 files changed, 74 insertions(+), 67 deletions(-) diff --git a/tests/run-make/print-cfg/rmake.rs b/tests/run-make/print-cfg/rmake.rs index 0f829c9a95fc..71db7b8a6937 100644 --- a/tests/run-make/print-cfg/rmake.rs +++ b/tests/run-make/print-cfg/rmake.rs @@ -14,36 +14,42 @@ use std::iter::FromIterator; use run_make_support::{rustc, tmp_dir}; -fn main() { - check( - /*target*/ "x86_64-pc-windows-gnu", - /*includes*/ &["windows", "target_arch=\"x86_64\""], - /*disallow*/ &["unix"], - ); - check( - /*target*/ "i686-pc-windows-msvc", - /*includes*/ &["windows", "target_env=\"msvc\""], - /*disallow*/ &["unix"], - ); - check( - /*target*/ "i686-apple-darwin", - /*includes*/ &["unix", "target_os=\"macos\"", "target_vendor=\"apple\""], - /*disallow*/ &["windows"], - ); - check( - /*target*/ "i686-unknown-linux-gnu", - /*includes*/ &["unix", "target_env=\"gnu\""], - /*disallow*/ &["windows"], - ); - check( - /*target*/ "arm-unknown-linux-gnueabihf", - /*includes*/ &["unix", "target_abi=\"eabihf\""], - /*disallow*/ &["windows"], - ); +struct PrintCfg { + target: &'static str, + includes: &'static [&'static str], + disallow: &'static [&'static str], } -fn check(target: &str, includes: &[&str], disallow: &[&str]) { - fn _inner(output: &str, includes: &[&str], disallow: &[&str]) { +fn main() { + check(PrintCfg { + target: "x86_64-pc-windows-gnu", + includes: &["windows", "target_arch=\"x86_64\""], + disallow: &["unix"], + }); + check(PrintCfg { + target: "i686-pc-windows-msvc", + includes: &["windows", "target_env=\"msvc\""], + disallow: &["unix"], + }); + check(PrintCfg { + target: "i686-apple-darwin", + includes: &["unix", "target_os=\"macos\"", "target_vendor=\"apple\""], + disallow: &["windows"], + }); + check(PrintCfg { + target: "i686-unknown-linux-gnu", + includes: &["unix", "target_env=\"gnu\""], + disallow: &["windows"], + }); + check(PrintCfg { + target: "arm-unknown-linux-gnueabihf", + includes: &["unix", "target_abi=\"eabihf\""], + disallow: &["windows"], + }); +} + +fn check(PrintCfg { target, includes, disallow }: PrintCfg) { + fn check_(output: &str, includes: &[&str], disallow: &[&str]) { let mut found = HashSet::::new(); let mut recorded = HashSet::::new(); @@ -82,7 +88,7 @@ fn check(target: &str, includes: &[&str], disallow: &[&str]) { let stdout = String::from_utf8(output.stdout).unwrap(); - _inner(&stdout, includes, disallow); + check_(&stdout, includes, disallow); } // --print=cfg=PATH @@ -95,6 +101,6 @@ fn check(target: &str, includes: &[&str], disallow: &[&str]) { let output = std::fs::read_to_string(&tmp_path).unwrap(); - _inner(&output, includes, disallow); + check_(&output, includes, disallow); } } diff --git a/tests/run-make/print-to-output/rmake.rs b/tests/run-make/print-to-output/rmake.rs index 91724b492f8d..8595a0c490b3 100644 --- a/tests/run-make/print-to-output/rmake.rs +++ b/tests/run-make/print-to-output/rmake.rs @@ -7,31 +7,37 @@ use std::ffi::OsString; use run_make_support::{rustc, target, tmp_dir}; -fn main() { - // Printed from CodegenBackend trait impl in rustc_codegen_llvm/src/lib.rs - check( - /*target*/ &target(), - /*option*/ "relocation-models", - /*includes*/ &["dynamic-no-pic"], - ); - - // Printed by compiler/rustc_codegen_llvm/src/llvm_util.rs - check( - /*target*/ "wasm32-unknown-unknown", - /*option*/ "target-features", - /*includes*/ &["reference-types"], - ); - - // Printed by C++ code in rustc_llvm/llvm-wrapper/PassWrapper.cpp - check( - /*target*/ "wasm32-unknown-unknown", - /*option*/ "target-cpus", - /*includes*/ &["generic"], - ); +struct Option<'a> { + target: &'a str, + option: &'static str, + includes: &'static [&'static str], } -fn check(target: &str, option: &str, includes: &[&str]) { - fn _inner(output: &str, includes: &[&str]) { +fn main() { + // Printed from CodegenBackend trait impl in rustc_codegen_llvm/src/lib.rs + check(Option { + target: &target(), + option: "relocation-models", + includes: &["dynamic-no-pic"], + }); + + // Printed by compiler/rustc_codegen_llvm/src/llvm_util.rs + check(Option { + target: "wasm32-unknown-unknown", + option: "target-features", + includes: &["reference-types"], + }); + + // Printed by C++ code in rustc_llvm/llvm-wrapper/PassWrapper.cpp + check(Option { + target: "wasm32-unknown-unknown", + option: "target-cpus", + includes: &["generic"], + }); +} + +fn check(args: Option) { + fn check_(output: &str, includes: &[&str]) { for i in includes { assert!(output.contains(i), "output doesn't contains: {}", i); } @@ -39,29 +45,24 @@ fn check(target: &str, option: &str, includes: &[&str]) { // --print={option} let stdout = { - let output = rustc().target(target).print(option).run(); + let output = rustc().target(args.target).print(args.option).run(); - let stdout = String::from_utf8(output.stdout).unwrap(); - - _inner(&stdout, includes); - - stdout + String::from_utf8(output.stdout).unwrap() }; // --print={option}=PATH let output = { - let tmp_path = tmp_dir().join(format!("{option}.txt")); - let mut print_arg = OsString::from(format!("--print={option}=")); + let tmp_path = tmp_dir().join(format!("{}.txt", args.option)); + let mut print_arg = OsString::from(format!("--print={}=", args.option)); print_arg.push(tmp_path.as_os_str()); - let _output = rustc().target(target).arg(print_arg).run(); + let _output = rustc().target(args.target).arg(print_arg).run(); - let output = std::fs::read_to_string(&tmp_path).unwrap(); - - _inner(&output, includes); - - output + std::fs::read_to_string(&tmp_path).unwrap() }; + check_(&stdout, args.includes); + check_(&output, args.includes); + assert_eq!(&stdout, &output); } From f5b3b400f7c5f85d3e0a821d83f41b2b71985f9b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 10 Apr 2024 20:14:18 +0200 Subject: [PATCH 123/279] Inline `clipboard.svg` into CSS --- src/librustdoc/html/static/css/rustdoc.css | 12 +++++++++++- src/librustdoc/html/static/images/clipboard.svg | 1 - src/librustdoc/html/static_files.rs | 1 - 3 files changed, 11 insertions(+), 3 deletions(-) delete mode 100644 src/librustdoc/html/static/images/clipboard.svg diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 74c9130fd77b..6b0a9c91e6cd 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1636,7 +1636,17 @@ a.tooltip:hover::after { } #copy-path::before { filter: var(--copy-path-img-filter); - content: url('clipboard-24048e6d87f63d07.svg'); + /* clipboard */ + content: url('data:image/svg+xml,\ +\ +\ +'); + width: 19px; + height: 18px; } #copy-path:hover::before { filter: var(--copy-path-img-hover-filter); diff --git a/src/librustdoc/html/static/images/clipboard.svg b/src/librustdoc/html/static/images/clipboard.svg deleted file mode 100644 index e437c83fb6b6..000000000000 --- a/src/librustdoc/html/static/images/clipboard.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index d8874c2fda0a..d78cf0a028a4 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -100,7 +100,6 @@ static_files! { storage_js => "static/js/storage.js", scrape_examples_js => "static/js/scrape-examples.js", wheel_svg => "static/images/wheel.svg", - clipboard_svg => "static/images/clipboard.svg", copyright => "static/COPYRIGHT.txt", license_apache => "static/LICENSE-APACHE.txt", license_mit => "static/LICENSE-MIT.txt", From f780913c722a78ab87e3fea10af4b75c0e4c1b66 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 10 Apr 2024 20:29:15 +0200 Subject: [PATCH 124/279] Inline `wheel.svg` into CSS --- src/librustdoc/html/static/css/rustdoc.css | 15 ++++++++++++++- src/librustdoc/html/static/images/wheel.svg | 1 - src/librustdoc/html/static_files.rs | 1 - 3 files changed, 14 insertions(+), 3 deletions(-) delete mode 100644 src/librustdoc/html/static/images/wheel.svg diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 6b0a9c91e6cd..887a5c39444f 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1608,7 +1608,20 @@ a.tooltip:hover::after { font-size: 0; } #settings-menu > a:before { - content: url('wheel-63255fc4502dca9a.svg'); + /* Wheel */ + content: url('data:image/svg+xml,\ + '); width: 22px; height: 22px; } diff --git a/src/librustdoc/html/static/images/wheel.svg b/src/librustdoc/html/static/images/wheel.svg deleted file mode 100644 index ba30f13dd58e..000000000000 --- a/src/librustdoc/html/static/images/wheel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index d78cf0a028a4..035376bace9c 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -99,7 +99,6 @@ static_files! { src_script_js => "static/js/src-script.js", storage_js => "static/js/storage.js", scrape_examples_js => "static/js/scrape-examples.js", - wheel_svg => "static/images/wheel.svg", copyright => "static/COPYRIGHT.txt", license_apache => "static/LICENSE-APACHE.txt", license_mit => "static/LICENSE-MIT.txt", From 5a3509c2f47758cc714381bc2f2fa68583bd5a5a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 10 Apr 2024 20:36:02 +0200 Subject: [PATCH 125/279] Add some missing comments to describe what the inlined SVG is --- src/librustdoc/html/static/css/rustdoc.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 887a5c39444f..80a4ea0424a2 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1133,6 +1133,7 @@ so that we can apply CSS-filters to change the arrow color in themes */ .setting-check input:checked { background-color: var(--settings-input-color); border-width: 1px; + /* cross-mark image in the settings checkboxes */ content: url('data:image/svg+xml,\ \ '); @@ -1627,6 +1628,7 @@ a.tooltip:hover::after { } #sidebar-button > a:before { + /* sidebar resizer image */ content: url('data:image/svg+xml,\ \ @@ -1860,6 +1862,7 @@ However, it's not needed with smaller screen width because the doc/code block is /* sidebar button opens modal use hamburger button */ .src #sidebar-button > a:before, .sidebar-menu-toggle:before { + /* hamburger button image */ content: url('data:image/svg+xml,\ '); @@ -1873,6 +1876,7 @@ However, it's not needed with smaller screen width because the doc/code block is /* src sidebar button opens a folder view */ .src #sidebar-button > a:before { + /* folder image */ content: url('data:image/svg+xml,\ \ From d9c0eb8084deb65de69b23a7714b66efbff7eb03 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 28 Apr 2024 18:22:37 +0200 Subject: [PATCH 126/279] Use `target_vendor = "apple"` instead of `target_os = "..."` --- library/std/src/fs/tests.rs | 35 +---- library/std/src/os/unix/net/mod.rs | 12 +- library/std/src/os/unix/net/stream.rs | 16 +-- library/std/src/os/unix/net/ucred.rs | 20 +-- library/std/src/os/unix/net/ucred/tests.rs | 17 +-- library/std/src/sys/pal/unix/args.rs | 15 +-- library/std/src/sys/pal/unix/fs.rs | 121 +++--------------- library/std/src/sys/pal/unix/mod.rs | 10 +- library/std/src/sys/pal/unix/os.rs | 30 +---- library/std/src/sys/pal/unix/rand.rs | 6 +- library/std/src/sys/pal/unix/thread.rs | 14 +- .../std/src/sys/pal/unix/thread_local_dtor.rs | 8 +- .../src/sys/pal/unix/thread_parking/mod.rs | 11 +- .../sys/pal/unix/thread_parking/pthread.rs | 26 +--- library/std/src/sys/pal/unix/time.rs | 24 +--- library/std/src/sys/sync/condvar/pthread.rs | 24 +--- library/std/src/sys_common/net.rs | 15 ++- library/std/src/thread/tests.rs | 6 +- 18 files changed, 74 insertions(+), 336 deletions(-) diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index ff399a0acd5f..dfa05671ab0f 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1657,23 +1657,9 @@ fn test_file_times() { let accessed = SystemTime::UNIX_EPOCH + Duration::from_secs(12345); let modified = SystemTime::UNIX_EPOCH + Duration::from_secs(54321); times = times.set_accessed(accessed).set_modified(modified); - #[cfg(any( - windows, - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "visionos", - target_os = "tvos", - ))] + #[cfg(any(windows, target_vendor = "apple"))] let created = SystemTime::UNIX_EPOCH + Duration::from_secs(32123); - #[cfg(any( - windows, - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "visionos", - target_os = "tvos", - ))] + #[cfg(any(windows, target_vendor = "apple"))] { times = times.set_created(created); } @@ -1698,27 +1684,14 @@ fn test_file_times() { let metadata = file.metadata().unwrap(); assert_eq!(metadata.accessed().unwrap(), accessed); assert_eq!(metadata.modified().unwrap(), modified); - #[cfg(any( - windows, - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "visionos", - target_os = "tvos", - ))] + #[cfg(any(windows, target_vendor = "apple"))] { assert_eq!(metadata.created().unwrap(), created); } } #[test] -#[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos" -))] +#[cfg(target_vendor = "apple")] fn test_file_times_pre_epoch_with_nanos() { #[cfg(target_os = "ios")] use crate::os::ios::fs::FileTimesExt; diff --git a/library/std/src/os/unix/net/mod.rs b/library/std/src/os/unix/net/mod.rs index 16d9cd915acc..3e45e3533ed2 100644 --- a/library/std/src/os/unix/net/mod.rs +++ b/library/std/src/os/unix/net/mod.rs @@ -17,14 +17,10 @@ mod tests; target_os = "linux", target_os = "dragonfly", target_os = "freebsd", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", - target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "nto", + target_vendor = "apple", ))] mod ucred; @@ -44,14 +40,10 @@ pub use self::stream::*; target_os = "linux", target_os = "dragonfly", target_os = "freebsd", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", - target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "nto", + target_vendor = "apple", ))] #[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")] pub use self::ucred::*; diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index 82b24dca1c41..19fc7b3d8532 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -3,14 +3,10 @@ target_os = "linux", target_os = "dragonfly", target_os = "freebsd", - target_os = "ios", - target_os = "tvos", - target_os = "macos", - target_os = "watchos", - target_os = "visionos", target_os = "netbsd", target_os = "openbsd", - target_os = "nto" + target_os = "nto", + target_vendor = "apple", ))] use super::{peer_cred, UCred}; #[cfg(any(doc, target_os = "android", target_os = "linux"))] @@ -231,14 +227,10 @@ impl UnixStream { target_os = "linux", target_os = "dragonfly", target_os = "freebsd", - target_os = "ios", - target_os = "tvos", - target_os = "macos", - target_os = "watchos", - target_os = "visionos", target_os = "netbsd", target_os = "openbsd", - target_os = "nto" + target_os = "nto", + target_vendor = "apple", ))] pub fn peer_cred(&self) -> io::Result { peer_cred(self) diff --git a/library/std/src/os/unix/net/ucred.rs b/library/std/src/os/unix/net/ucred.rs index 3a752a53a506..1497e730bbf1 100644 --- a/library/std/src/os/unix/net/ucred.rs +++ b/library/std/src/os/unix/net/ucred.rs @@ -35,14 +35,8 @@ pub(super) use self::impl_linux::peer_cred; ))] pub(super) use self::impl_bsd::peer_cred; -#[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos" -))] -pub(super) use self::impl_mac::peer_cred; +#[cfg(target_vendor = "apple")] +pub(super) use self::impl_apple::peer_cred; #[cfg(any(target_os = "linux", target_os = "android"))] mod impl_linux { @@ -103,14 +97,8 @@ mod impl_bsd { } } -#[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos" -))] -mod impl_mac { +#[cfg(target_vendor = "apple")] +mod impl_apple { use super::UCred; use crate::os::unix::io::AsRawFd; use crate::os::unix::net::UnixStream; diff --git a/library/std/src/os/unix/net/ucred/tests.rs b/library/std/src/os/unix/net/ucred/tests.rs index 2a0797877c6f..a6cc81318fc0 100644 --- a/library/std/src/os/unix/net/ucred/tests.rs +++ b/library/std/src/os/unix/net/ucred/tests.rs @@ -7,12 +7,8 @@ use libc::{getegid, geteuid, getpid}; target_os = "linux", target_os = "dragonfly", target_os = "freebsd", - target_os = "ios", - target_os = "tvos", - target_os = "macos", - target_os = "watchos", - target_os = "visionos", - target_os = "openbsd" + target_os = "openbsd", + target_vendor = "apple", ))] fn test_socket_pair() { // Create two connected sockets and get their peer credentials. They should be equal. @@ -28,14 +24,7 @@ fn test_socket_pair() { } #[test] -#[cfg(any( - target_os = "linux", - target_os = "ios", - target_os = "macos", - target_os = "watchos", - target_os = "visionos", - target_os = "tvos", -))] +#[cfg(any(target_os = "linux", target_vendor = "apple"))] fn test_socket_pair_pids(arg: Type) -> RetType { // Create two connected sockets and get their peer credentials. let (sock_a, sock_b) = UnixStream::pair().unwrap(); diff --git a/library/std/src/sys/pal/unix/args.rs b/library/std/src/sys/pal/unix/args.rs index afe703bcb2f2..2a3298e8b4c9 100644 --- a/library/std/src/sys/pal/unix/args.rs +++ b/library/std/src/sys/pal/unix/args.rs @@ -168,13 +168,7 @@ mod imp { } } -#[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "visionos", - target_os = "tvos" -))] +#[cfg(target_vendor = "apple")] mod imp { use super::Args; use crate::ffi::CStr; @@ -215,12 +209,7 @@ mod imp { // for i in (0..[args count]) // res.push([args objectAtIndex:i]) // res - #[cfg(any( - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos" - ))] + #[cfg(not(target_os = "macos"))] pub fn args() -> Args { use crate::ffi::{c_char, c_void, OsString}; use crate::mem; diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index abd32b819e03..809185f75047 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -20,14 +20,7 @@ use crate::sys::time::SystemTime; use crate::sys::{cvt, cvt_r}; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; -#[cfg(any( - all(target_os = "linux", target_env = "gnu"), - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", -))] +#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))] use crate::sys::weak::syscall; #[cfg(any(target_os = "android", target_os = "macos", target_os = "solaris"))] use crate::sys::weak::weak; @@ -35,13 +28,9 @@ use crate::sys::weak::weak; use libc::{c_int, mode_t}; #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", target_os = "solaris", - all(target_os = "linux", target_env = "gnu") + all(target_os = "linux", target_env = "gnu"), + target_vendor = "apple", ))] use libc::c_char; #[cfg(any( @@ -375,13 +364,7 @@ pub struct FilePermissions { pub struct FileTimes { accessed: Option, modified: Option, - #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "visionos", - target_os = "tvos" - ))] + #[cfg(target_vendor = "apple")] created: Option, } @@ -554,15 +537,7 @@ impl FileAttr { SystemTime::new(self.stat.st_atim.tv_sec as i64, self.stat.st_atim.tv_nsec as i64) } - #[cfg(any( - target_os = "freebsd", - target_os = "openbsd", - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", - ))] + #[cfg(any(target_os = "freebsd", target_os = "openbsd", target_vendor = "apple"))] pub fn created(&self) -> io::Result { SystemTime::new(self.stat.st_birthtime as i64, self.stat.st_birthtime_nsec as i64) } @@ -570,12 +545,8 @@ impl FileAttr { #[cfg(not(any( target_os = "freebsd", target_os = "openbsd", - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", target_os = "vita", + target_vendor = "apple", )))] pub fn created(&self) -> io::Result { cfg_has_statx! { @@ -655,13 +626,7 @@ impl FileTimes { self.modified = Some(t); } - #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "visionos", - target_os = "tvos" - ))] + #[cfg(target_vendor = "apple")] pub fn set_created(&mut self, t: SystemTime) { self.created = Some(t); } @@ -994,11 +959,6 @@ impl DirEntry { } #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", target_os = "linux", target_os = "emscripten", target_os = "android", @@ -1015,6 +975,7 @@ impl DirEntry { target_os = "aix", target_os = "nto", target_os = "hurd", + target_vendor = "apple", ))] pub fn ino(&self) -> u64 { self.entry.d_ino as u64 @@ -1031,15 +992,11 @@ impl DirEntry { } #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", target_os = "netbsd", target_os = "openbsd", target_os = "freebsd", - target_os = "dragonfly" + target_os = "dragonfly", + target_vendor = "apple", ))] fn name_bytes(&self) -> &[u8] { use crate::slice; @@ -1051,15 +1008,11 @@ impl DirEntry { } } #[cfg(not(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", target_os = "netbsd", target_os = "openbsd", target_os = "freebsd", - target_os = "dragonfly" + target_os = "dragonfly", + target_vendor = "apple", )))] fn name_bytes(&self) -> &[u8] { self.name_cstr().to_bytes() @@ -1237,23 +1190,11 @@ impl File { cvt_r(|| unsafe { os_fsync(self.as_raw_fd()) })?; return Ok(()); - #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", - ))] + #[cfg(target_vendor = "apple")] unsafe fn os_fsync(fd: c_int) -> c_int { libc::fcntl(fd, libc::F_FULLFSYNC) } - #[cfg(not(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", - )))] + #[cfg(not(target_vendor = "apple"))] unsafe fn os_fsync(fd: c_int) -> c_int { libc::fsync(fd) } @@ -1263,13 +1204,7 @@ impl File { cvt_r(|| unsafe { os_datasync(self.as_raw_fd()) })?; return Ok(()); - #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", - ))] + #[cfg(target_vendor = "apple")] unsafe fn os_datasync(fd: c_int) -> c_int { libc::fcntl(fd, libc::F_FULLFSYNC) } @@ -1288,16 +1223,12 @@ impl File { #[cfg(not(any( target_os = "android", target_os = "freebsd", - target_os = "ios", - target_os = "tvos", target_os = "linux", - target_os = "macos", target_os = "netbsd", target_os = "openbsd", - target_os = "watchos", - target_os = "visionos", target_os = "nto", target_os = "hurd", + target_vendor = "apple", )))] unsafe fn os_datasync(fd: c_int) -> c_int { libc::fsync(fd) @@ -1406,7 +1337,7 @@ impl File { io::ErrorKind::Unsupported, "setting file times not supported", )) - } else if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] { + } else if #[cfg(target_vendor = "apple")] { let mut buf = [mem::MaybeUninit::::uninit(); 3]; let mut num_times = 0; let mut attrlist: libc::attrlist = unsafe { mem::zeroed() }; @@ -1938,15 +1869,7 @@ fn open_to_and_set_permissions( Ok((writer, writer_metadata)) } -#[cfg(not(any( - target_os = "linux", - target_os = "android", - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", -)))] +#[cfg(not(any(target_os = "linux", target_os = "android", target_vendor = "apple")))] pub fn copy(from: &Path, to: &Path) -> io::Result { let (mut reader, reader_metadata) = open_from(from)?; let (mut writer, _) = open_to_and_set_permissions(to, reader_metadata)?; @@ -1972,13 +1895,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { } } -#[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "visionos", - target_os = "tvos" -))] +#[cfg(target_vendor = "apple")] pub fn copy(from: &Path, to: &Path) -> io::Result { use crate::sync::atomic::{AtomicBool, Ordering}; diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 3ef43a923a37..01d7fb31d7d6 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -78,16 +78,12 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { target_os = "emscripten", target_os = "fuchsia", target_os = "vxworks", - // The poll on Darwin doesn't set POLLNVAL for closed fds. - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", target_os = "redox", target_os = "l4re", target_os = "horizon", target_os = "vita", + // The poll on Darwin doesn't set POLLNVAL for closed fds. + target_vendor = "apple", )))] 'poll: { use crate::sys::os::errno; @@ -406,7 +402,7 @@ cfg_if::cfg_if! { } else if #[cfg(target_os = "macos")] { #[link(name = "System")] extern "C" {} - } else if #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] { + } else if #[cfg(all(target_vendor = "apple", not(target_os = "macos")))] { #[link(name = "System")] #[link(name = "objc")] #[link(name = "Foundation", kind = "framework")] diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index 96492fedece7..3a281525f8df 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -63,17 +63,7 @@ extern "C" { )] #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), link_name = "___errno")] #[cfg_attr(target_os = "nto", link_name = "__get_errno_ptr")] - #[cfg_attr( - any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "freebsd", - target_os = "watchos", - target_os = "visionos", - ), - link_name = "__error" - )] + #[cfg_attr(any(target_os = "freebsd", target_vendor = "apple"), link_name = "__error")] #[cfg_attr(target_os = "haiku", link_name = "_errnop")] #[cfg_attr(target_os = "aix", link_name = "_Errno")] fn errno_location() -> *mut c_int; @@ -431,13 +421,7 @@ pub fn current_exe() -> io::Result { Ok(PathBuf::from(OsString::from_vec(e))) } -#[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "visionos", - target_os = "tvos" -))] +#[cfg(target_vendor = "apple")] pub fn current_exe() -> io::Result { unsafe { let mut sz: u32 = 0; @@ -703,32 +687,26 @@ pub fn home_dir() -> Option { #[cfg(any( target_os = "android", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", target_os = "emscripten", target_os = "redox", target_os = "vxworks", target_os = "espidf", target_os = "horizon", target_os = "vita", + all(target_vendor = "apple", not(target_os = "macos")), ))] unsafe fn fallback() -> Option { None } #[cfg(not(any( target_os = "android", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", target_os = "emscripten", target_os = "redox", target_os = "vxworks", target_os = "espidf", target_os = "horizon", target_os = "vita", + all(target_vendor = "apple", not(target_os = "macos")), )))] unsafe fn fallback() -> Option { let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) { diff --git a/library/std/src/sys/pal/unix/rand.rs b/library/std/src/sys/pal/unix/rand.rs index de087d98eb8b..d8f227b4ef44 100644 --- a/library/std/src/sys/pal/unix/rand.rs +++ b/library/std/src/sys/pal/unix/rand.rs @@ -12,11 +12,6 @@ pub fn hashmap_random_keys() -> (u64, u64) { #[cfg(all( unix, - not(target_os = "macos"), - not(target_os = "ios"), - not(target_os = "tvos"), - not(target_os = "watchos"), - not(target_os = "visionos"), not(target_os = "openbsd"), not(target_os = "netbsd"), not(target_os = "fuchsia"), @@ -24,6 +19,7 @@ pub fn hashmap_random_keys() -> (u64, u64) { not(target_os = "vxworks"), not(target_os = "emscripten"), not(target_os = "vita"), + not(target_vendor = "apple"), ))] mod imp { use crate::fs::File; diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 6a6bfc77a854..faa70ff8e790 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -150,13 +150,7 @@ impl Thread { } } - #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "visionos", - target_os = "tvos" - ))] + #[cfg(target_vendor = "apple")] pub fn set_name(name: &CStr) { unsafe { let name = truncate_cstr::<{ libc::MAXTHREADNAMESIZE }>(name); @@ -301,14 +295,10 @@ impl Drop for Thread { #[cfg(any( target_os = "linux", - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", target_os = "nto", target_os = "solaris", target_os = "illumos", + target_vendor = "apple", ))] fn truncate_cstr(cstr: &CStr) -> [libc::c_char; MAX_WITH_NUL] { let mut result = [0; MAX_WITH_NUL]; diff --git a/library/std/src/sys/pal/unix/thread_local_dtor.rs b/library/std/src/sys/pal/unix/thread_local_dtor.rs index 1164c1782f4b..75db6e112ed3 100644 --- a/library/std/src/sys/pal/unix/thread_local_dtor.rs +++ b/library/std/src/sys/pal/unix/thread_local_dtor.rs @@ -76,13 +76,7 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { // workaround below is to register, via _tlv_atexit, a custom DTOR list once per // thread. thread_local dtors are pushed to the DTOR list without calling // _tlv_atexit. -#[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "visionos", - target_os = "tvos" -))] +#[cfg(target_vendor = "apple")] pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { use crate::cell::{Cell, RefCell}; use crate::ptr; diff --git a/library/std/src/sys/pal/unix/thread_parking/mod.rs b/library/std/src/sys/pal/unix/thread_parking/mod.rs index 3348d4b366d2..c7fa39f07b64 100644 --- a/library/std/src/sys/pal/unix/thread_parking/mod.rs +++ b/library/std/src/sys/pal/unix/thread_parking/mod.rs @@ -11,16 +11,7 @@ )))] cfg_if::cfg_if! { - if #[cfg(all( - any( - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "visionos", - target_os = "tvos", - ), - not(miri), - ))] { + if #[cfg(all(target_vendor = "apple", not(miri)))] { mod darwin; pub use darwin::Parker; } else if #[cfg(target_os = "netbsd")] { diff --git a/library/std/src/sys/pal/unix/thread_parking/pthread.rs b/library/std/src/sys/pal/unix/thread_parking/pthread.rs index d0ad3e2ce3ee..8e295453d767 100644 --- a/library/std/src/sys/pal/unix/thread_parking/pthread.rs +++ b/library/std/src/sys/pal/unix/thread_parking/pthread.rs @@ -43,15 +43,7 @@ unsafe fn wait_timeout( ) { // Use the system clock on systems that do not support pthread_condattr_setclock. // This unfortunately results in problems when the system time changes. - #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", - target_os = "espidf", - target_os = "horizon", - ))] + #[cfg(any(target_os = "espidf", target_os = "horizon", target_vendor = "apple"))] let (now, dur) = { use crate::cmp::min; use crate::sys::time::SystemTime; @@ -72,15 +64,7 @@ unsafe fn wait_timeout( (now, dur) }; // Use the monotonic clock on other systems. - #[cfg(not(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", - target_os = "espidf", - target_os = "horizon", - )))] + #[cfg(not(any(target_os = "espidf", target_os = "horizon", target_vendor = "apple")))] let (now, dur) = { use crate::sys::time::Timespec; @@ -122,15 +106,11 @@ impl Parker { cfg_if::cfg_if! { if #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", target_os = "l4re", target_os = "android", target_os = "redox", target_os = "vita", + target_vendor = "apple", ))] { addr_of_mut!((*parker).cvar).write(UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER)); } else if #[cfg(any(target_os = "espidf", target_os = "horizon"))] { diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index e69775be8cf8..535fe6b27d91 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -86,13 +86,7 @@ impl Timespec { // Please note that Apple OS nonetheless accepts the standard unix format when // setting file times, which makes this compensation round-trippable and generally // transparent. - #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", - ))] + #[cfg(target_vendor = "apple")] let (tv_sec, tv_nsec) = if (tv_sec <= 0 && tv_sec > i64::MIN) && (tv_nsec < 0 && tv_nsec > -1_000_000_000) { (tv_sec - 1, tv_nsec + 1_000_000_000) @@ -275,21 +269,9 @@ impl Instant { // // Instant on macos was historically implemented using mach_absolute_time; // we preserve this value domain out of an abundance of caution. - #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "visionos", - target_os = "tvos" - ))] + #[cfg(target_vendor = "apple")] const clock_id: libc::clockid_t = libc::CLOCK_UPTIME_RAW; - #[cfg(not(any( - target_os = "macos", - target_os = "ios", - target_os = "watchos", - target_os = "visionos", - target_os = "tvos" - )))] + #[cfg(not(target_vendor = "apple"))] const clock_id: libc::clockid_t = libc::CLOCK_MONOTONIC; Instant { t: Timespec::now(clock_id) } } diff --git a/library/std/src/sys/sync/condvar/pthread.rs b/library/std/src/sys/sync/condvar/pthread.rs index 0475f9850786..a2a96410d932 100644 --- a/library/std/src/sys/sync/condvar/pthread.rs +++ b/library/std/src/sys/sync/condvar/pthread.rs @@ -30,14 +30,10 @@ impl LazyInit for AllocatedCondvar { cfg_if::cfg_if! { if #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", target_os = "l4re", target_os = "android", - target_os = "redox" + target_os = "redox", + target_vendor = "apple", ))] { // `pthread_condattr_setclock` is unfortunately not supported on these platforms. } else if #[cfg(any(target_os = "espidf", target_os = "horizon"))] { @@ -124,14 +120,10 @@ impl Condvar { // default system clock). This approach avoids all problems that result // from changes made to the system time. #[cfg(not(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", target_os = "android", target_os = "espidf", - target_os = "horizon" + target_os = "horizon", + target_vendor = "apple", )))] pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { use crate::sys::time::Timespec; @@ -160,14 +152,10 @@ impl Condvar { // https://github.com/llvm-mirror/libcxx/blob/release_35/src/condition_variable.cpp#L46 // https://github.com/llvm-mirror/libcxx/blob/release_35/include/__mutex_base#L367 #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", target_os = "android", target_os = "espidf", - target_os = "horizon" + target_os = "horizon", + target_vendor = "apple", ))] pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { use crate::sys::time::SystemTime; diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs index 6a268633f72c..95ca67fc2e0b 100644 --- a/library/std/src/sys_common/net.rs +++ b/library/std/src/sys_common/net.rs @@ -17,10 +17,17 @@ use crate::ffi::{c_int, c_void}; cfg_if::cfg_if! { if #[cfg(any( - target_os = "dragonfly", target_os = "freebsd", - target_os = "ios", target_os = "tvos", target_os = "macos", target_os = "watchos", target_os = "visionos", - target_os = "openbsd", target_os = "netbsd", target_os = "illumos", - target_os = "solaris", target_os = "haiku", target_os = "l4re", target_os = "nto"))] { + target_os = "dragonfly", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "illumos", + target_os = "solaris", + target_os = "haiku", + target_os = "l4re", + target_os = "nto", + target_vendor = "apple", + ))] { use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; use crate::sys::net::netc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; } else { diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs index 494513f2c75c..1fb1333be0e4 100644 --- a/library/std/src/thread/tests.rs +++ b/library/std/src/thread/tests.rs @@ -40,11 +40,7 @@ fn test_named_thread() { #[cfg(any( // Note: musl didn't add pthread_getname_np until 1.2.3 all(target_os = "linux", target_env = "gnu"), - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos", + target_vendor = "apple", ))] #[test] fn test_named_thread_truncation() { From ca79086c874278bf362391996be7b49ccf30160a Mon Sep 17 00:00:00 2001 From: George Bateman Date: Sun, 28 Apr 2024 18:36:08 +0100 Subject: [PATCH 127/279] Fix #124478 - offset_of! returns a temporary This was due to the must_use() call. Adding HIR's OffsetOf to the must_use checking within the compiler avoids this issue. --- compiler/rustc_lint/src/unused.rs | 1 + library/core/src/mem/mod.rs | 4 +-- tests/ui/offset-of/offset-of-dst-field.stderr | 28 +++++++++---------- tests/ui/offset-of/offset-of-must-use.rs | 2 +- tests/ui/offset-of/offset-of-must-use.stderr | 4 +-- tests/ui/offset-of/offset-of-self.rs | 5 ++-- tests/ui/offset-of/offset-of-self.stderr | 10 +++---- 7 files changed, 28 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 0b0949e4dd86..98f2e95a3894 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -176,6 +176,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { | hir::BinOpKind::Shr => Some("bitwise operation"), }, hir::ExprKind::AddrOf(..) => Some("borrow"), + hir::ExprKind::OffsetOf(..) => Some("`offset_of` call"), hir::ExprKind::Unary(..) => Some("unary operation"), _ => None, }; diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 75d42edbaa03..9054ade2d796 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1340,8 +1340,8 @@ impl SizedTypeProperties for T {} /// assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0); /// ``` #[stable(feature = "offset_of", since = "1.77.0")] -#[allow_internal_unstable(builtin_syntax, hint_must_use)] +#[allow_internal_unstable(builtin_syntax)] pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) { // The `{}` is for better error messages - crate::hint::must_use({builtin # offset_of($Container, $($fields)+)}) + {builtin # offset_of($Container, $($fields)+)} } diff --git a/tests/ui/offset-of/offset-of-dst-field.stderr b/tests/ui/offset-of/offset-of-dst-field.stderr index 753ba809e7da..adfd16c6f2b9 100644 --- a/tests/ui/offset-of/offset-of-dst-field.stderr +++ b/tests/ui/offset-of/offset-of-dst-field.stderr @@ -34,20 +34,6 @@ LL | offset_of!((u8, dyn Trait), 1); = help: the trait `Sized` is not implemented for `dyn Trait` = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:44:5 - | -LL | offset_of!(Delta, z); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: within `Alpha`, the trait `Sized` is not implemented for `[u8]`, which is required by `Alpha: Sized` -note: required because it appears within the type `Alpha` - --> $DIR/offset-of-dst-field.rs:5:8 - | -LL | struct Alpha { - | ^^^^^ - = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) - error[E0277]: the size for values of type `Extern` cannot be known at compilation time --> $DIR/offset-of-dst-field.rs:45:5 | @@ -66,6 +52,20 @@ LL | offset_of!(Delta, z); = help: the trait `Sized` is not implemented for `dyn Trait` = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/offset-of-dst-field.rs:44:5 + | +LL | offset_of!(Delta, z); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `Alpha`, the trait `Sized` is not implemented for `[u8]`, which is required by `Alpha: Sized` +note: required because it appears within the type `Alpha` + --> $DIR/offset-of-dst-field.rs:5:8 + | +LL | struct Alpha { + | ^^^^^ + = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/offset-of-dst-field.rs:50:5 | diff --git a/tests/ui/offset-of/offset-of-must-use.rs b/tests/ui/offset-of/offset-of-must-use.rs index f0c242891d8f..87918b8ff953 100644 --- a/tests/ui/offset-of/offset-of-must-use.rs +++ b/tests/ui/offset-of/offset-of-must-use.rs @@ -4,5 +4,5 @@ fn main() { core::mem::offset_of!((String,), 0); - //~^ WARN unused return value of `must_use` that must be used + //~^ WARN unused `offset_of` call that must be used } diff --git a/tests/ui/offset-of/offset-of-must-use.stderr b/tests/ui/offset-of/offset-of-must-use.stderr index b6d88e098d00..9f0e37a59f43 100644 --- a/tests/ui/offset-of/offset-of-must-use.stderr +++ b/tests/ui/offset-of/offset-of-must-use.stderr @@ -1,8 +1,8 @@ -warning: unused return value of `must_use` that must be used +warning: unused `offset_of` call that must be used --> $DIR/offset-of-must-use.rs:6:5 | LL | core::mem::offset_of!((String,), 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `offset_of` call produces a value | note: the lint level is defined here --> $DIR/offset-of-must-use.rs:3:9 diff --git a/tests/ui/offset-of/offset-of-self.rs b/tests/ui/offset-of/offset-of-self.rs index 1558e13b5309..51b1a0b24273 100644 --- a/tests/ui/offset-of/offset-of-self.rs +++ b/tests/ui/offset-of/offset-of-self.rs @@ -23,8 +23,9 @@ impl S { fn offs_in_c() -> usize { offset_of!(C, w) } - fn offs_in_c_colon() -> usize { - offset_of!(C::, w) + // Put offset_of in a slice - test #124478. + fn offs_in_c_colon() -> &'static [usize] { + &[offset_of!(C::, w)] } } diff --git a/tests/ui/offset-of/offset-of-self.stderr b/tests/ui/offset-of/offset-of-self.stderr index 7c7576e066b6..a2104a438ad8 100644 --- a/tests/ui/offset-of/offset-of-self.stderr +++ b/tests/ui/offset-of/offset-of-self.stderr @@ -5,7 +5,7 @@ LL | offset_of!(Self, Self::v); | ^^^^^^^ error[E0412]: cannot find type `S` in module `self` - --> $DIR/offset-of-self.rs:34:26 + --> $DIR/offset-of-self.rs:35:26 | LL | offset_of!(self::S, v); | ^ not found in `self` @@ -21,7 +21,7 @@ LL + offset_of!(S, v); | error[E0411]: cannot find type `Self` in this scope - --> $DIR/offset-of-self.rs:51:16 + --> $DIR/offset-of-self.rs:52:16 | LL | fn main() { | ---- `Self` not allowed in a function @@ -38,13 +38,13 @@ LL | offset_of!(S, Self); = note: available fields are: `v`, `w` error[E0616]: field `v` of struct `T` is private - --> $DIR/offset-of-self.rs:40:30 + --> $DIR/offset-of-self.rs:41:30 | LL | offset_of!(Self, v) | ^ private field error[E0609]: no field `self` on type `S` - --> $DIR/offset-of-self.rs:53:19 + --> $DIR/offset-of-self.rs:54:19 | LL | offset_of!(S, self); | ^^^^ @@ -52,7 +52,7 @@ LL | offset_of!(S, self); = note: available fields are: `v`, `w` error[E0609]: no field `self` on type `u8` - --> $DIR/offset-of-self.rs:54:21 + --> $DIR/offset-of-self.rs:55:21 | LL | offset_of!(S, v.self); | ^^^^ From e2861d56522591758b54200d75d7220c519fcf62 Mon Sep 17 00:00:00 2001 From: Aneesh Kadiyala <143342960+ARandomDev99@users.noreply.github.com> Date: Sat, 30 Mar 2024 11:11:16 +0530 Subject: [PATCH 128/279] Encourage using `LateLintPass` --- book/src/development/adding_lints.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/book/src/development/adding_lints.md b/book/src/development/adding_lints.md index e30a5f9fe10b..9fc286e9e685 100644 --- a/book/src/development/adding_lints.md +++ b/book/src/development/adding_lints.md @@ -297,10 +297,10 @@ This is good, because it makes writing this particular lint less complicated. We have to make this decision with every new Clippy lint. It boils down to using either [`EarlyLintPass`][early_lint_pass] or [`LateLintPass`][late_lint_pass]. -In short, the `LateLintPass` has access to type information while the -`EarlyLintPass` doesn't. If you don't need access to type information, use the -`EarlyLintPass`. The `EarlyLintPass` is also faster. However, linting speed -hasn't really been a concern with Clippy so far. +In short, the `EarlyLintPass` runs before type checking and +[HIR](https://rustc-dev-guide.rust-lang.org/hir.html) lowering and the `LateLintPass` +has access to type information. Consider using the `LateLintPass` unless you need +something specific from the `EarlyLintPass`. Since we don't need type information for checking the function name, we used `--pass=early` when running the new lint automation and all the imports were From 79c6d9196658c1f304972bae3c5a6567816e9888 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 28 Apr 2024 17:34:17 +0200 Subject: [PATCH 129/279] Fix available_parallelism on watchOS and visionOS Both `sysconf` and `_SC_NPROCESSORS_ONLN` is available on all Apple platforms. --- library/std/src/sys/pal/unix/thread.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index faa70ff8e790..853ef8736de2 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -315,11 +315,9 @@ pub fn available_parallelism() -> io::Result> { target_os = "emscripten", target_os = "fuchsia", target_os = "hurd", - target_os = "ios", - target_os = "tvos", target_os = "linux", - target_os = "macos", target_os = "aix", + target_vendor = "apple", ))] { #[allow(unused_assignments)] #[allow(unused_mut)] From a6d9da6b2acbf6985199c99e6dbdc1847ed3ead3 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 28 Apr 2024 17:37:04 +0200 Subject: [PATCH 130/279] Fix SIGEMT and SIGINFO parsing on watchOS and visionOS --- library/std/src/sys/pal/unix/process/process_unix.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index d65657790c48..0ce09c90bbd9 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -1040,24 +1040,20 @@ fn signal_string(signal: i32) -> &'static str { #[cfg(any(target_os = "linux", target_os = "nto"))] libc::SIGPWR => " (SIGPWR)", #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd", target_os = "dragonfly", target_os = "nto", + target_vendor = "apple", ))] libc::SIGEMT => " (SIGEMT)", #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd", - target_os = "dragonfly" + target_os = "dragonfly", + target_vendor = "apple", ))] libc::SIGINFO => " (SIGINFO)", #[cfg(target_os = "hurd")] From 4284bca7209fc9eb03a8db5a388479ff723cc70d Mon Sep 17 00:00:00 2001 From: est31 Date: Sun, 28 Apr 2024 15:14:32 +0200 Subject: [PATCH 131/279] Add a note to the ArbitraryExpressionInPattern error --- compiler/rustc_ast_lowering/messages.ftl | 1 + compiler/rustc_ast_lowering/src/errors.rs | 2 ++ compiler/rustc_ast_lowering/src/pat.rs | 6 +++++- tests/ui/issues/issue-43250.stderr | 4 ++++ tests/ui/lowering/expr-in-pat-issue-99380.rs | 11 +++++++++++ tests/ui/lowering/expr-in-pat-issue-99380.stderr | 10 ++++++++++ tests/ui/macros/vec-macro-in-pattern.stderr | 1 + tests/ui/match/expr_before_ident_pat.stderr | 2 ++ tests/ui/pattern/issue-92074-macro-ice.stderr | 3 +++ 9 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 tests/ui/lowering/expr-in-pat-issue-99380.rs create mode 100644 tests/ui/lowering/expr-in-pat-issue-99380.stderr diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index 73001c9990c8..aa5a85b9c4ca 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -5,6 +5,7 @@ ast_lowering_abi_specified_multiple_times = ast_lowering_arbitrary_expression_in_pattern = arbitrary expressions aren't allowed in patterns + .pattern_from_macro_note = the :expr fragment specifier forces the metavariable's content to be an expression ast_lowering_argument = argument diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 6f70e135c72a..02744d16b422 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -368,6 +368,8 @@ pub struct NeverPatternWithGuard { pub struct ArbitraryExpressionInPattern { #[primary_span] pub span: Span, + #[note(ast_lowering_pattern_from_macro_note)] + pub pattern_from_macro_note: bool, } #[derive(Diagnostic)] diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 118a7322fbdf..32de07a0755e 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -339,7 +339,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ExprKind::Path(..) if allow_paths => {} ExprKind::Unary(UnOp::Neg, inner) if matches!(inner.kind, ExprKind::Lit(_)) => {} _ => { - let guar = self.dcx().emit_err(ArbitraryExpressionInPattern { span: expr.span }); + let pattern_from_macro = expr.is_approximately_pattern(); + let guar = self.dcx().emit_err(ArbitraryExpressionInPattern { + span: expr.span, + pattern_from_macro_note: pattern_from_macro, + }); return self.arena.alloc(self.expr_err(expr.span, guar)); } } diff --git a/tests/ui/issues/issue-43250.stderr b/tests/ui/issues/issue-43250.stderr index f729c5cf10ce..01c22a9e7916 100644 --- a/tests/ui/issues/issue-43250.stderr +++ b/tests/ui/issues/issue-43250.stderr @@ -3,12 +3,16 @@ error: arbitrary expressions aren't allowed in patterns | LL | m!(y); | ^ + | + = note: the :expr fragment specifier forces the metavariable's content to be an expression error: arbitrary expressions aren't allowed in patterns --> $DIR/issue-43250.rs:11:8 | LL | m!(C); | ^ + | + = note: the :expr fragment specifier forces the metavariable's content to be an expression error: aborting due to 2 previous errors diff --git a/tests/ui/lowering/expr-in-pat-issue-99380.rs b/tests/ui/lowering/expr-in-pat-issue-99380.rs new file mode 100644 index 000000000000..1d4a047f717f --- /dev/null +++ b/tests/ui/lowering/expr-in-pat-issue-99380.rs @@ -0,0 +1,11 @@ +macro_rules! foo { + ($p:expr) => { + if let $p = Some(42) { + return; + } + }; +} + +fn main() { + foo!(Some(3)); //~ ERROR arbitrary expressions aren't allowed in patterns +} diff --git a/tests/ui/lowering/expr-in-pat-issue-99380.stderr b/tests/ui/lowering/expr-in-pat-issue-99380.stderr new file mode 100644 index 000000000000..7438bba270c7 --- /dev/null +++ b/tests/ui/lowering/expr-in-pat-issue-99380.stderr @@ -0,0 +1,10 @@ +error: arbitrary expressions aren't allowed in patterns + --> $DIR/expr-in-pat-issue-99380.rs:10:10 + | +LL | foo!(Some(3)); + | ^^^^^^^ + | + = note: the :expr fragment specifier forces the metavariable's content to be an expression + +error: aborting due to 1 previous error + diff --git a/tests/ui/macros/vec-macro-in-pattern.stderr b/tests/ui/macros/vec-macro-in-pattern.stderr index 447f5dcf8644..7c87f3b7b8e6 100644 --- a/tests/ui/macros/vec-macro-in-pattern.stderr +++ b/tests/ui/macros/vec-macro-in-pattern.stderr @@ -4,6 +4,7 @@ error: arbitrary expressions aren't allowed in patterns LL | Some(vec![43]) => {} | ^^^^^^^^ | + = note: the :expr fragment specifier forces the metavariable's content to be an expression = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/match/expr_before_ident_pat.stderr b/tests/ui/match/expr_before_ident_pat.stderr index 57a2d2b26cff..2f59573b53f4 100644 --- a/tests/ui/match/expr_before_ident_pat.stderr +++ b/tests/ui/match/expr_before_ident_pat.stderr @@ -9,6 +9,8 @@ error: arbitrary expressions aren't allowed in patterns | LL | funny!(a, a); | ^ + | + = note: the :expr fragment specifier forces the metavariable's content to be an expression error: aborting due to 2 previous errors diff --git a/tests/ui/pattern/issue-92074-macro-ice.stderr b/tests/ui/pattern/issue-92074-macro-ice.stderr index b340afff010f..bf53eb4bbcd4 100644 --- a/tests/ui/pattern/issue-92074-macro-ice.stderr +++ b/tests/ui/pattern/issue-92074-macro-ice.stderr @@ -7,6 +7,7 @@ LL | () => { force_expr!(Vec::new()) } LL | assert!(matches!(x, En::A(make_vec!()))); | ----------- in this macro invocation | + = note: the :expr fragment specifier forces the metavariable's content to be an expression = note: this error originates in the macro `make_vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: arbitrary expressions aren't allowed in patterns @@ -18,6 +19,7 @@ LL | () => { force_pat!(get_usize(), get_usize()) } LL | assert!(matches!(5, make_pat!())); | ----------- in this macro invocation | + = note: the :expr fragment specifier forces the metavariable's content to be an expression = note: this error originates in the macro `make_pat` (in Nightly builds, run with -Z macro-backtrace for more info) error: arbitrary expressions aren't allowed in patterns @@ -29,6 +31,7 @@ LL | () => { force_pat!(get_usize(), get_usize()) } LL | assert!(matches!(5, make_pat!())); | ----------- in this macro invocation | + = note: the :expr fragment specifier forces the metavariable's content to be an expression = note: this error originates in the macro `make_pat` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors From 214d588a5b5e8bf9adcfa9408fd2b0ebbe3fd734 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 28 Apr 2024 18:04:08 +0200 Subject: [PATCH 132/279] Fix va_list on watchOS and visionOS --- library/core/src/ffi/mod.rs | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index cbdae2ac7663..27dacbb23d95 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -213,7 +213,7 @@ impl fmt::Debug for c_void { not(target_arch = "s390x"), not(target_arch = "x86_64") ), - all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios", target_os = "tvos")), + all(target_arch = "aarch64", target_vendor = "apple"), target_family = "wasm", target_os = "uefi", windows, @@ -241,7 +241,7 @@ pub struct VaListImpl<'f> { not(target_arch = "s390x"), not(target_arch = "x86_64") ), - all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios", target_os = "tvos")), + all(target_arch = "aarch64", target_vendor = "apple"), target_family = "wasm", target_os = "uefi", windows, @@ -265,7 +265,7 @@ impl<'f> fmt::Debug for VaListImpl<'f> { /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf #[cfg(all( target_arch = "aarch64", - not(any(target_os = "macos", target_os = "ios", target_os = "tvos")), + not(target_vendor = "apple"), not(target_os = "uefi"), not(windows), ))] @@ -362,10 +362,7 @@ pub struct VaList<'a, 'f: 'a> { not(target_arch = "s390x"), not(target_arch = "x86_64") ), - all( - target_arch = "aarch64", - any(target_os = "macos", target_os = "ios", target_os = "tvos") - ), + all(target_arch = "aarch64", target_vendor = "apple"), target_family = "wasm", target_os = "uefi", windows, @@ -379,10 +376,7 @@ pub struct VaList<'a, 'f: 'a> { target_arch = "s390x", target_arch = "x86_64" ), - any( - not(target_arch = "aarch64"), - not(any(target_os = "macos", target_os = "ios", target_os = "tvos")) - ), + any(not(target_arch = "aarch64"), not(target_vendor = "apple")), not(target_family = "wasm"), not(target_os = "uefi"), not(windows), @@ -399,7 +393,7 @@ pub struct VaList<'a, 'f: 'a> { not(target_arch = "s390x"), not(target_arch = "x86_64") ), - all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios", target_os = "tvos")), + all(target_arch = "aarch64", target_vendor = "apple"), target_family = "wasm", target_os = "uefi", windows, @@ -425,10 +419,7 @@ impl<'f> VaListImpl<'f> { target_arch = "s390x", target_arch = "x86_64" ), - any( - not(target_arch = "aarch64"), - not(any(target_os = "macos", target_os = "ios", target_os = "tvos")) - ), + any(not(target_arch = "aarch64"), not(target_vendor = "apple")), not(target_family = "wasm"), not(target_os = "uefi"), not(windows), From 6b488cd3021a7438cb58c11af822e206b05d038d Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 28 Apr 2024 18:11:43 +0200 Subject: [PATCH 133/279] Also raise fd limit on tvOS when testing --- src/tools/compiletest/src/raise_fd_limit.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/compiletest/src/raise_fd_limit.rs b/src/tools/compiletest/src/raise_fd_limit.rs index a4235381beb6..218bea68a218 100644 --- a/src/tools/compiletest/src/raise_fd_limit.rs +++ b/src/tools/compiletest/src/raise_fd_limit.rs @@ -4,7 +4,7 @@ /// on the number of cores available. /// /// This fixes issue #7772. -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos", target_os = "visionos"))] +#[cfg(target_vendor = "apple")] #[allow(non_camel_case_types)] pub unsafe fn raise_fd_limit() { use std::cmp; @@ -50,5 +50,5 @@ pub unsafe fn raise_fd_limit() { } } -#[cfg(not(any(target_os = "macos", target_os = "ios")))] +#[cfg(not(target_vendor = "apple"))] pub unsafe fn raise_fd_limit() {} From 87efce4fa22f51075e1fd25904f757f783eebfdc Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Sun, 28 Apr 2024 00:01:14 +0200 Subject: [PATCH 134/279] configurably allow `useless_vec` in tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds a `àllow-useless-vec-in-test` configuration which, when set to `true` will allow the `useless_vec` lint in `#[test]` functions and code within `#[cfg(test)]`. It also moves a `is_in_test` helper to `clippy_utils`. --- CHANGELOG.md | 1 + book/src/lint_configuration.md | 10 +++++++ clippy_config/src/conf.rs | 4 +++ clippy_lints/src/dbg_macro.rs | 10 +++---- clippy_lints/src/lib.rs | 2 ++ clippy_lints/src/vec.rs | 6 ++++- clippy_utils/src/lib.rs | 5 ++++ .../toml_unknown_key/conf_unknown_key.stderr | 3 +++ tests/ui-toml/useless_vec/clippy.toml | 1 + tests/ui-toml/useless_vec/useless_vec.fixed | 26 +++++++++++++++++++ tests/ui-toml/useless_vec/useless_vec.rs | 26 +++++++++++++++++++ tests/ui-toml/useless_vec/useless_vec.stderr | 11 ++++++++ 12 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 tests/ui-toml/useless_vec/clippy.toml create mode 100644 tests/ui-toml/useless_vec/useless_vec.fixed create mode 100644 tests/ui-toml/useless_vec/useless_vec.rs create mode 100644 tests/ui-toml/useless_vec/useless_vec.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index bd3a04e34ae3..12d4918ca55e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5891,6 +5891,7 @@ Released 2018-09-13 [`allow-print-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-print-in-tests [`allow-private-module-inception`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-private-module-inception [`allow-unwrap-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-unwrap-in-tests +[`allow-useless-vec-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-useless-vec-in-tests [`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles [`allowed-duplicate-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-duplicate-crates [`allowed-idents-below-min-chars`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-idents-below-min-chars diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index fe0e9b80b11e..f6af9810ca16 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -132,6 +132,16 @@ Whether `unwrap` should be allowed in test functions or `#[cfg(test)]` * [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used) +## `allow-useless-vec-in-tests` +Whether `useless_vec` should ignore test functions or `#[cfg(test)]` + +**Default Value:** `false` + +--- +**Affected lints:** +* [`useless_vec`](https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec) + + ## `allowed-dotfiles` Additional dotfiles (files or directories starting with a dot) to allow diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index bbce4180dc4d..5cfcbdb57d73 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -463,6 +463,10 @@ define_Conf! { /// /// Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]` (allow_print_in_tests: bool = false), + /// Lint: USELESS_VEC. + /// + /// Whether `useless_vec` should ignore test functions or `#[cfg(test)]` + (allow_useless_vec_in_tests: bool = false), /// Lint: RESULT_LARGE_ERR. /// /// The maximum size of the `Err`-variant in a `Result` returned from a function diff --git a/clippy_lints/src/dbg_macro.rs b/clippy_lints/src/dbg_macro.rs index e22967674319..db5937266047 100644 --- a/clippy_lints/src/dbg_macro.rs +++ b/clippy_lints/src/dbg_macro.rs @@ -1,10 +1,10 @@ use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::is_in_test; use clippy_utils::macros::{macro_backtrace, MacroCall}; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::{is_in_cfg_test, is_in_test_function}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind, HirId, Node}; +use rustc_hir::{Expr, ExprKind, Node}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::impl_lint_pass; @@ -63,7 +63,7 @@ impl LateLintPass<'_> for DbgMacro { !in_external_macro(cx.sess(), macro_call.span) && self.checked_dbg_call_site.insert(macro_call.span) && // allows `dbg!` in test code if allow-dbg-in-test is set to true in clippy.toml - !(self.allow_dbg_in_tests && is_in_test(cx, expr.hir_id)) + !(self.allow_dbg_in_tests && is_in_test(cx.tcx, expr.hir_id)) { let mut applicability = Applicability::MachineApplicable; @@ -129,10 +129,6 @@ impl LateLintPass<'_> for DbgMacro { } } -fn is_in_test(cx: &LateContext<'_>, hir_id: HirId) -> bool { - is_in_test_function(cx.tcx, hir_id) || is_in_cfg_test(cx.tcx, hir_id) -} - fn first_dbg_macro_in_expansion(cx: &LateContext<'_>, span: Span) -> Option { macro_backtrace(span).find(|mc| cx.tcx.is_diagnostic_item(sym::dbg_macro, mc.def_id)) } diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index e2aac58bf979..2c44c3881aa7 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -535,6 +535,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { allow_print_in_tests, allow_private_module_inception, allow_unwrap_in_tests, + allow_useless_vec_in_tests, ref allowed_dotfiles, ref allowed_idents_below_min_chars, ref allowed_scripts, @@ -754,6 +755,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { too_large_for_stack, msrv: msrv(), span_to_lint_map: BTreeMap::new(), + allow_in_test: allow_useless_vec_in_tests, }) }); store.register_late_pass(|_| Box::new(panic_unimplemented::PanicUnimplemented)); diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index 27ead55bf39c..9edf7579d482 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -7,7 +7,7 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::source::snippet_opt; use clippy_utils::ty::is_copy; use clippy_utils::visitors::for_each_local_use_after_expr; -use clippy_utils::{get_parent_expr, higher, is_trait_method}; +use clippy_utils::{get_parent_expr, higher, is_in_test, is_trait_method}; use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, LetStmt, Mutability, Node, Pat, PatKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -22,6 +22,7 @@ pub struct UselessVec { pub too_large_for_stack: u64, pub msrv: Msrv, pub span_to_lint_map: BTreeMap>, + pub allow_in_test: bool, } declare_clippy_lint! { @@ -57,6 +58,9 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec { let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows()) else { return; }; + if self.allow_in_test && is_in_test(cx.tcx, expr.hir_id) { + return; + }; // the parent callsite of this `vec!` expression, or span to the borrowed one such as `&vec!` let callsite = expr.span.parent_callsite().unwrap_or(expr.span); diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index fccd75d81533..26ee5225f999 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -2548,6 +2548,11 @@ pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool { .any(|parent_id| is_cfg_test(tcx, parent_id)) } +/// Checks if the node is in a `#[test]` function or has any parent node marked `#[cfg(test)]` +pub fn is_in_test(tcx: TyCtxt<'_>, hir_id: HirId) -> bool { + is_in_test_function(tcx, hir_id) || is_in_cfg_test(tcx, hir_id) +} + /// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied. pub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { let hir = tcx.hir(); diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 24645b61fdb0..722e9b3bc8d4 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -11,6 +11,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect allow-print-in-tests allow-private-module-inception allow-unwrap-in-tests + allow-useless-vec-in-tests allowed-dotfiles allowed-duplicate-crates allowed-idents-below-min-chars @@ -91,6 +92,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect allow-print-in-tests allow-private-module-inception allow-unwrap-in-tests + allow-useless-vec-in-tests allowed-dotfiles allowed-duplicate-crates allowed-idents-below-min-chars @@ -171,6 +173,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni allow-print-in-tests allow-private-module-inception allow-unwrap-in-tests + allow-useless-vec-in-tests allowed-dotfiles allowed-duplicate-crates allowed-idents-below-min-chars diff --git a/tests/ui-toml/useless_vec/clippy.toml b/tests/ui-toml/useless_vec/clippy.toml new file mode 100644 index 000000000000..230ca2d0ab72 --- /dev/null +++ b/tests/ui-toml/useless_vec/clippy.toml @@ -0,0 +1 @@ +allow-useless-vec-in-tests = true diff --git a/tests/ui-toml/useless_vec/useless_vec.fixed b/tests/ui-toml/useless_vec/useless_vec.fixed new file mode 100644 index 000000000000..08323a0dcc90 --- /dev/null +++ b/tests/ui-toml/useless_vec/useless_vec.fixed @@ -0,0 +1,26 @@ +//@compile-flags: --test +#![warn(clippy::useless_vec)] +#![allow(clippy::unnecessary_operation, clippy::no_effect)] + +fn foo(_: &[u32]) {} + +fn main() { + foo(&[1_u32]); +} + +#[test] +pub fn in_test() { + foo(&vec![2_u32]); +} + +#[cfg(test)] +fn in_cfg_test() { + foo(&vec![3_u32]); +} + +#[cfg(test)] +mod mod1 { + fn in_cfg_test_mod() { + super::foo(&vec![4_u32]); + } +} diff --git a/tests/ui-toml/useless_vec/useless_vec.rs b/tests/ui-toml/useless_vec/useless_vec.rs new file mode 100644 index 000000000000..1f4b27c53429 --- /dev/null +++ b/tests/ui-toml/useless_vec/useless_vec.rs @@ -0,0 +1,26 @@ +//@compile-flags: --test +#![warn(clippy::useless_vec)] +#![allow(clippy::unnecessary_operation, clippy::no_effect)] + +fn foo(_: &[u32]) {} + +fn main() { + foo(&vec![1_u32]); +} + +#[test] +pub fn in_test() { + foo(&vec![2_u32]); +} + +#[cfg(test)] +fn in_cfg_test() { + foo(&vec![3_u32]); +} + +#[cfg(test)] +mod mod1 { + fn in_cfg_test_mod() { + super::foo(&vec![4_u32]); + } +} diff --git a/tests/ui-toml/useless_vec/useless_vec.stderr b/tests/ui-toml/useless_vec/useless_vec.stderr new file mode 100644 index 000000000000..633110c3c8d9 --- /dev/null +++ b/tests/ui-toml/useless_vec/useless_vec.stderr @@ -0,0 +1,11 @@ +error: useless use of `vec!` + --> tests/ui-toml/useless_vec/useless_vec.rs:8:9 + | +LL | foo(&vec![1_u32]); + | ^^^^^^^^^^^^ help: you can use a slice directly: `&[1_u32]` + | + = note: `-D clippy::useless-vec` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]` + +error: aborting due to 1 previous error + From 2348eb271c95f7ba75333f41b1a303b3b7261b4f Mon Sep 17 00:00:00 2001 From: George Bateman Date: Sun, 28 Apr 2024 21:10:09 +0100 Subject: [PATCH 135/279] Update mir-opt tests, add proper regression test --- .../offset_of.concrete.GVN.panic-abort.diff | 112 +++++------------- .../offset_of.concrete.GVN.panic-unwind.diff | 112 +++++------------- .../offset_of.generic.GVN.panic-abort.diff | 99 ++++------------ .../offset_of.generic.GVN.panic-unwind.diff | 99 ++++------------ ...oncrete.DataflowConstProp.panic-abort.diff | 64 +++------- ...ncrete.DataflowConstProp.panic-unwind.diff | 64 +++------- ...generic.DataflowConstProp.panic-abort.diff | 58 +++------ ...eneric.DataflowConstProp.panic-unwind.diff | 58 +++------ .../mir-opt/dataflow-const-prop/offset_of.rs | 16 +-- tests/ui/offset-of/offset-of-self.rs | 5 +- tests/ui/offset-of/offset-of-self.stderr | 10 +- tests/ui/offset-of/offset-of-temporaries.rs | 23 ++++ 12 files changed, 202 insertions(+), 518 deletions(-) create mode 100644 tests/ui/offset-of/offset-of-temporaries.rs diff --git a/tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-abort.diff b/tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-abort.diff index 5d94797905db..77a2c5bcccc7 100644 --- a/tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-abort.diff +++ b/tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-abort.diff @@ -4,33 +4,26 @@ fn concrete() -> () { let mut _0: (); let _1: usize; - let mut _2: usize; - let mut _4: usize; - let mut _6: usize; - let mut _8: usize; - let mut _10: usize; - let mut _12: usize; - let mut _14: usize; scope 1 { debug x => _1; - let _3: usize; + let _2: usize; scope 2 { - debug y => _3; - let _5: usize; + debug y => _2; + let _3: usize; scope 3 { - debug z0 => _5; - let _7: usize; + debug z0 => _3; + let _4: usize; scope 4 { - debug z1 => _7; - let _9: usize; + debug z1 => _4; + let _5: usize; scope 5 { - debug eA0 => _9; - let _11: usize; + debug eA0 => _5; + let _6: usize; scope 6 { - debug eA1 => _11; - let _13: usize; + debug eA1 => _6; + let _7: usize; scope 7 { - debug eC => _13; + debug eC => _7; } } } @@ -41,82 +34,33 @@ bb0: { StorageLive(_1); +- _1 = OffsetOf(Alpha, [(0, 0)]); ++ _1 = const 4_usize; StorageLive(_2); -- _2 = OffsetOf(Alpha, [(0, 0)]); -- _1 = must_use::(move _2) -> [return: bb1, unwind unreachable]; -+ _2 = const 4_usize; -+ _1 = must_use::(const 4_usize) -> [return: bb1, unwind unreachable]; - } - - bb1: { - StorageDead(_2); +- _2 = OffsetOf(Alpha, [(0, 1)]); ++ _2 = const 0_usize; StorageLive(_3); +- _3 = OffsetOf(Alpha, [(0, 2), (0, 0)]); ++ _3 = const 2_usize; StorageLive(_4); -- _4 = OffsetOf(Alpha, [(0, 1)]); -- _3 = must_use::(move _4) -> [return: bb2, unwind unreachable]; -+ _4 = const 0_usize; -+ _3 = must_use::(const 0_usize) -> [return: bb2, unwind unreachable]; - } - - bb2: { - StorageDead(_4); +- _4 = OffsetOf(Alpha, [(0, 2), (0, 1)]); ++ _4 = const 3_usize; StorageLive(_5); +- _5 = OffsetOf(Epsilon, [(0, 0)]); ++ _5 = const 1_usize; StorageLive(_6); -- _6 = OffsetOf(Alpha, [(0, 2), (0, 0)]); -- _5 = must_use::(move _6) -> [return: bb3, unwind unreachable]; +- _6 = OffsetOf(Epsilon, [(0, 1)]); + _6 = const 2_usize; -+ _5 = must_use::(const 2_usize) -> [return: bb3, unwind unreachable]; - } - - bb3: { - StorageDead(_6); StorageLive(_7); - StorageLive(_8); -- _8 = OffsetOf(Alpha, [(0, 2), (0, 1)]); -- _7 = must_use::(move _8) -> [return: bb4, unwind unreachable]; -+ _8 = const 3_usize; -+ _7 = must_use::(const 3_usize) -> [return: bb4, unwind unreachable]; - } - - bb4: { - StorageDead(_8); - StorageLive(_9); - StorageLive(_10); -- _10 = OffsetOf(Epsilon, [(0, 0)]); -- _9 = must_use::(move _10) -> [return: bb5, unwind unreachable]; -+ _10 = const 1_usize; -+ _9 = must_use::(const 1_usize) -> [return: bb5, unwind unreachable]; - } - - bb5: { - StorageDead(_10); - StorageLive(_11); - StorageLive(_12); -- _12 = OffsetOf(Epsilon, [(0, 1)]); -- _11 = must_use::(move _12) -> [return: bb6, unwind unreachable]; -+ _12 = const 2_usize; -+ _11 = must_use::(const 2_usize) -> [return: bb6, unwind unreachable]; - } - - bb6: { - StorageDead(_12); - StorageLive(_13); - StorageLive(_14); -- _14 = OffsetOf(Epsilon, [(2, 0)]); -- _13 = must_use::(move _14) -> [return: bb7, unwind unreachable]; -+ _14 = const 4_usize; -+ _13 = must_use::(const 4_usize) -> [return: bb7, unwind unreachable]; - } - - bb7: { - StorageDead(_14); +- _7 = OffsetOf(Epsilon, [(2, 0)]); ++ _7 = const 4_usize; _0 = const (); - StorageDead(_13); - StorageDead(_11); - StorageDead(_9); StorageDead(_7); + StorageDead(_6); StorageDead(_5); + StorageDead(_4); StorageDead(_3); + StorageDead(_2); StorageDead(_1); return; } diff --git a/tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-unwind.diff index 4d890742ee99..77a2c5bcccc7 100644 --- a/tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-unwind.diff +++ b/tests/mir-opt/const_prop/offset_of.concrete.GVN.panic-unwind.diff @@ -4,33 +4,26 @@ fn concrete() -> () { let mut _0: (); let _1: usize; - let mut _2: usize; - let mut _4: usize; - let mut _6: usize; - let mut _8: usize; - let mut _10: usize; - let mut _12: usize; - let mut _14: usize; scope 1 { debug x => _1; - let _3: usize; + let _2: usize; scope 2 { - debug y => _3; - let _5: usize; + debug y => _2; + let _3: usize; scope 3 { - debug z0 => _5; - let _7: usize; + debug z0 => _3; + let _4: usize; scope 4 { - debug z1 => _7; - let _9: usize; + debug z1 => _4; + let _5: usize; scope 5 { - debug eA0 => _9; - let _11: usize; + debug eA0 => _5; + let _6: usize; scope 6 { - debug eA1 => _11; - let _13: usize; + debug eA1 => _6; + let _7: usize; scope 7 { - debug eC => _13; + debug eC => _7; } } } @@ -41,82 +34,33 @@ bb0: { StorageLive(_1); +- _1 = OffsetOf(Alpha, [(0, 0)]); ++ _1 = const 4_usize; StorageLive(_2); -- _2 = OffsetOf(Alpha, [(0, 0)]); -- _1 = must_use::(move _2) -> [return: bb1, unwind continue]; -+ _2 = const 4_usize; -+ _1 = must_use::(const 4_usize) -> [return: bb1, unwind continue]; - } - - bb1: { - StorageDead(_2); +- _2 = OffsetOf(Alpha, [(0, 1)]); ++ _2 = const 0_usize; StorageLive(_3); +- _3 = OffsetOf(Alpha, [(0, 2), (0, 0)]); ++ _3 = const 2_usize; StorageLive(_4); -- _4 = OffsetOf(Alpha, [(0, 1)]); -- _3 = must_use::(move _4) -> [return: bb2, unwind continue]; -+ _4 = const 0_usize; -+ _3 = must_use::(const 0_usize) -> [return: bb2, unwind continue]; - } - - bb2: { - StorageDead(_4); +- _4 = OffsetOf(Alpha, [(0, 2), (0, 1)]); ++ _4 = const 3_usize; StorageLive(_5); +- _5 = OffsetOf(Epsilon, [(0, 0)]); ++ _5 = const 1_usize; StorageLive(_6); -- _6 = OffsetOf(Alpha, [(0, 2), (0, 0)]); -- _5 = must_use::(move _6) -> [return: bb3, unwind continue]; +- _6 = OffsetOf(Epsilon, [(0, 1)]); + _6 = const 2_usize; -+ _5 = must_use::(const 2_usize) -> [return: bb3, unwind continue]; - } - - bb3: { - StorageDead(_6); StorageLive(_7); - StorageLive(_8); -- _8 = OffsetOf(Alpha, [(0, 2), (0, 1)]); -- _7 = must_use::(move _8) -> [return: bb4, unwind continue]; -+ _8 = const 3_usize; -+ _7 = must_use::(const 3_usize) -> [return: bb4, unwind continue]; - } - - bb4: { - StorageDead(_8); - StorageLive(_9); - StorageLive(_10); -- _10 = OffsetOf(Epsilon, [(0, 0)]); -- _9 = must_use::(move _10) -> [return: bb5, unwind continue]; -+ _10 = const 1_usize; -+ _9 = must_use::(const 1_usize) -> [return: bb5, unwind continue]; - } - - bb5: { - StorageDead(_10); - StorageLive(_11); - StorageLive(_12); -- _12 = OffsetOf(Epsilon, [(0, 1)]); -- _11 = must_use::(move _12) -> [return: bb6, unwind continue]; -+ _12 = const 2_usize; -+ _11 = must_use::(const 2_usize) -> [return: bb6, unwind continue]; - } - - bb6: { - StorageDead(_12); - StorageLive(_13); - StorageLive(_14); -- _14 = OffsetOf(Epsilon, [(2, 0)]); -- _13 = must_use::(move _14) -> [return: bb7, unwind continue]; -+ _14 = const 4_usize; -+ _13 = must_use::(const 4_usize) -> [return: bb7, unwind continue]; - } - - bb7: { - StorageDead(_14); +- _7 = OffsetOf(Epsilon, [(2, 0)]); ++ _7 = const 4_usize; _0 = const (); - StorageDead(_13); - StorageDead(_11); - StorageDead(_9); StorageDead(_7); + StorageDead(_6); StorageDead(_5); + StorageDead(_4); StorageDead(_3); + StorageDead(_2); StorageDead(_1); return; } diff --git a/tests/mir-opt/const_prop/offset_of.generic.GVN.panic-abort.diff b/tests/mir-opt/const_prop/offset_of.generic.GVN.panic-abort.diff index 025241dd1bf9..130c31eff8cc 100644 --- a/tests/mir-opt/const_prop/offset_of.generic.GVN.panic-abort.diff +++ b/tests/mir-opt/const_prop/offset_of.generic.GVN.panic-abort.diff @@ -4,33 +4,26 @@ fn generic() -> () { let mut _0: (); let _1: usize; - let mut _2: usize; - let mut _4: usize; - let mut _6: usize; - let mut _8: usize; - let mut _10: usize; - let mut _12: usize; - let mut _14: usize; scope 1 { debug gx => _1; - let _3: usize; + let _2: usize; scope 2 { - debug gy => _3; - let _5: usize; + debug gy => _2; + let _3: usize; scope 3 { - debug dx => _5; - let _7: usize; + debug dx => _3; + let _4: usize; scope 4 { - debug dy => _7; - let _9: usize; + debug dy => _4; + let _5: usize; scope 5 { - debug zA0 => _9; - let _11: usize; + debug zA0 => _5; + let _6: usize; scope 6 { - debug zA1 => _11; - let _13: usize; + debug zA1 => _6; + let _7: usize; scope 7 { - debug zB => _13; + debug zB => _7; } } } @@ -41,72 +34,28 @@ bb0: { StorageLive(_1); + _1 = OffsetOf(Gamma, [(0, 0)]); StorageLive(_2); - _2 = OffsetOf(Gamma, [(0, 0)]); - _1 = must_use::(move _2) -> [return: bb1, unwind unreachable]; - } - - bb1: { - StorageDead(_2); + _2 = OffsetOf(Gamma, [(0, 1)]); StorageLive(_3); +- _3 = OffsetOf(Delta, [(0, 1)]); ++ _3 = const 0_usize; StorageLive(_4); - _4 = OffsetOf(Gamma, [(0, 1)]); - _3 = must_use::(move _4) -> [return: bb2, unwind unreachable]; - } - - bb2: { - StorageDead(_4); +- _4 = OffsetOf(Delta, [(0, 2)]); ++ _4 = const 2_usize; StorageLive(_5); + _5 = OffsetOf(Zeta, [(0, 0)]); StorageLive(_6); -- _6 = OffsetOf(Delta, [(0, 1)]); -- _5 = must_use::(move _6) -> [return: bb3, unwind unreachable]; -+ _6 = const 0_usize; -+ _5 = must_use::(const 0_usize) -> [return: bb3, unwind unreachable]; - } - - bb3: { - StorageDead(_6); + _6 = OffsetOf(Zeta, [(0, 1)]); StorageLive(_7); - StorageLive(_8); -- _8 = OffsetOf(Delta, [(0, 2)]); -- _7 = must_use::(move _8) -> [return: bb4, unwind unreachable]; -+ _8 = const 2_usize; -+ _7 = must_use::(const 2_usize) -> [return: bb4, unwind unreachable]; - } - - bb4: { - StorageDead(_8); - StorageLive(_9); - StorageLive(_10); - _10 = OffsetOf(Zeta, [(0, 0)]); - _9 = must_use::(move _10) -> [return: bb5, unwind unreachable]; - } - - bb5: { - StorageDead(_10); - StorageLive(_11); - StorageLive(_12); - _12 = OffsetOf(Zeta, [(0, 1)]); - _11 = must_use::(move _12) -> [return: bb6, unwind unreachable]; - } - - bb6: { - StorageDead(_12); - StorageLive(_13); - StorageLive(_14); - _14 = OffsetOf(Zeta, [(1, 0)]); - _13 = must_use::(move _14) -> [return: bb7, unwind unreachable]; - } - - bb7: { - StorageDead(_14); + _7 = OffsetOf(Zeta, [(1, 0)]); _0 = const (); - StorageDead(_13); - StorageDead(_11); - StorageDead(_9); StorageDead(_7); + StorageDead(_6); StorageDead(_5); + StorageDead(_4); StorageDead(_3); + StorageDead(_2); StorageDead(_1); return; } diff --git a/tests/mir-opt/const_prop/offset_of.generic.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/offset_of.generic.GVN.panic-unwind.diff index 27f2b2f7355e..130c31eff8cc 100644 --- a/tests/mir-opt/const_prop/offset_of.generic.GVN.panic-unwind.diff +++ b/tests/mir-opt/const_prop/offset_of.generic.GVN.panic-unwind.diff @@ -4,33 +4,26 @@ fn generic() -> () { let mut _0: (); let _1: usize; - let mut _2: usize; - let mut _4: usize; - let mut _6: usize; - let mut _8: usize; - let mut _10: usize; - let mut _12: usize; - let mut _14: usize; scope 1 { debug gx => _1; - let _3: usize; + let _2: usize; scope 2 { - debug gy => _3; - let _5: usize; + debug gy => _2; + let _3: usize; scope 3 { - debug dx => _5; - let _7: usize; + debug dx => _3; + let _4: usize; scope 4 { - debug dy => _7; - let _9: usize; + debug dy => _4; + let _5: usize; scope 5 { - debug zA0 => _9; - let _11: usize; + debug zA0 => _5; + let _6: usize; scope 6 { - debug zA1 => _11; - let _13: usize; + debug zA1 => _6; + let _7: usize; scope 7 { - debug zB => _13; + debug zB => _7; } } } @@ -41,72 +34,28 @@ bb0: { StorageLive(_1); + _1 = OffsetOf(Gamma, [(0, 0)]); StorageLive(_2); - _2 = OffsetOf(Gamma, [(0, 0)]); - _1 = must_use::(move _2) -> [return: bb1, unwind continue]; - } - - bb1: { - StorageDead(_2); + _2 = OffsetOf(Gamma, [(0, 1)]); StorageLive(_3); +- _3 = OffsetOf(Delta, [(0, 1)]); ++ _3 = const 0_usize; StorageLive(_4); - _4 = OffsetOf(Gamma, [(0, 1)]); - _3 = must_use::(move _4) -> [return: bb2, unwind continue]; - } - - bb2: { - StorageDead(_4); +- _4 = OffsetOf(Delta, [(0, 2)]); ++ _4 = const 2_usize; StorageLive(_5); + _5 = OffsetOf(Zeta, [(0, 0)]); StorageLive(_6); -- _6 = OffsetOf(Delta, [(0, 1)]); -- _5 = must_use::(move _6) -> [return: bb3, unwind continue]; -+ _6 = const 0_usize; -+ _5 = must_use::(const 0_usize) -> [return: bb3, unwind continue]; - } - - bb3: { - StorageDead(_6); + _6 = OffsetOf(Zeta, [(0, 1)]); StorageLive(_7); - StorageLive(_8); -- _8 = OffsetOf(Delta, [(0, 2)]); -- _7 = must_use::(move _8) -> [return: bb4, unwind continue]; -+ _8 = const 2_usize; -+ _7 = must_use::(const 2_usize) -> [return: bb4, unwind continue]; - } - - bb4: { - StorageDead(_8); - StorageLive(_9); - StorageLive(_10); - _10 = OffsetOf(Zeta, [(0, 0)]); - _9 = must_use::(move _10) -> [return: bb5, unwind continue]; - } - - bb5: { - StorageDead(_10); - StorageLive(_11); - StorageLive(_12); - _12 = OffsetOf(Zeta, [(0, 1)]); - _11 = must_use::(move _12) -> [return: bb6, unwind continue]; - } - - bb6: { - StorageDead(_12); - StorageLive(_13); - StorageLive(_14); - _14 = OffsetOf(Zeta, [(1, 0)]); - _13 = must_use::(move _14) -> [return: bb7, unwind continue]; - } - - bb7: { - StorageDead(_14); + _7 = OffsetOf(Zeta, [(1, 0)]); _0 = const (); - StorageDead(_13); - StorageDead(_11); - StorageDead(_9); StorageDead(_7); + StorageDead(_6); StorageDead(_5); + StorageDead(_4); StorageDead(_3); + StorageDead(_2); StorageDead(_1); return; } diff --git a/tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-abort.diff index f8f891750337..92691d0f8070 100644 --- a/tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-abort.diff @@ -4,21 +4,17 @@ fn concrete() -> () { let mut _0: (); let _1: usize; - let mut _2: usize; - let mut _4: usize; - let mut _6: usize; - let mut _8: usize; scope 1 { debug x => _1; - let _3: usize; + let _2: usize; scope 2 { - debug y => _3; - let _5: usize; + debug y => _2; + let _3: usize; scope 3 { - debug z0 => _5; - let _7: usize; + debug z0 => _3; + let _4: usize; scope 4 { - debug z1 => _7; + debug z1 => _4; } } } @@ -26,49 +22,21 @@ bb0: { StorageLive(_1); +- _1 = OffsetOf(Alpha, [(0, 0)]); ++ _1 = const 4_usize; StorageLive(_2); -- _2 = OffsetOf(Alpha, [(0, 0)]); -- _1 = must_use::(move _2) -> [return: bb1, unwind unreachable]; -+ _2 = const 4_usize; -+ _1 = must_use::(const 4_usize) -> [return: bb1, unwind unreachable]; - } - - bb1: { - StorageDead(_2); +- _2 = OffsetOf(Alpha, [(0, 1)]); ++ _2 = const 0_usize; StorageLive(_3); +- _3 = OffsetOf(Alpha, [(0, 2), (0, 0)]); ++ _3 = const 2_usize; StorageLive(_4); -- _4 = OffsetOf(Alpha, [(0, 1)]); -- _3 = must_use::(move _4) -> [return: bb2, unwind unreachable]; -+ _4 = const 0_usize; -+ _3 = must_use::(const 0_usize) -> [return: bb2, unwind unreachable]; - } - - bb2: { - StorageDead(_4); - StorageLive(_5); - StorageLive(_6); -- _6 = OffsetOf(Alpha, [(0, 2), (0, 0)]); -- _5 = must_use::(move _6) -> [return: bb3, unwind unreachable]; -+ _6 = const 2_usize; -+ _5 = must_use::(const 2_usize) -> [return: bb3, unwind unreachable]; - } - - bb3: { - StorageDead(_6); - StorageLive(_7); - StorageLive(_8); -- _8 = OffsetOf(Alpha, [(0, 2), (0, 1)]); -- _7 = must_use::(move _8) -> [return: bb4, unwind unreachable]; -+ _8 = const 3_usize; -+ _7 = must_use::(const 3_usize) -> [return: bb4, unwind unreachable]; - } - - bb4: { - StorageDead(_8); +- _4 = OffsetOf(Alpha, [(0, 2), (0, 1)]); ++ _4 = const 3_usize; _0 = const (); - StorageDead(_7); - StorageDead(_5); + StorageDead(_4); StorageDead(_3); + StorageDead(_2); StorageDead(_1); return; } diff --git a/tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-unwind.diff index d4f8cb66704a..92691d0f8070 100644 --- a/tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/offset_of.concrete.DataflowConstProp.panic-unwind.diff @@ -4,21 +4,17 @@ fn concrete() -> () { let mut _0: (); let _1: usize; - let mut _2: usize; - let mut _4: usize; - let mut _6: usize; - let mut _8: usize; scope 1 { debug x => _1; - let _3: usize; + let _2: usize; scope 2 { - debug y => _3; - let _5: usize; + debug y => _2; + let _3: usize; scope 3 { - debug z0 => _5; - let _7: usize; + debug z0 => _3; + let _4: usize; scope 4 { - debug z1 => _7; + debug z1 => _4; } } } @@ -26,49 +22,21 @@ bb0: { StorageLive(_1); +- _1 = OffsetOf(Alpha, [(0, 0)]); ++ _1 = const 4_usize; StorageLive(_2); -- _2 = OffsetOf(Alpha, [(0, 0)]); -- _1 = must_use::(move _2) -> [return: bb1, unwind continue]; -+ _2 = const 4_usize; -+ _1 = must_use::(const 4_usize) -> [return: bb1, unwind continue]; - } - - bb1: { - StorageDead(_2); +- _2 = OffsetOf(Alpha, [(0, 1)]); ++ _2 = const 0_usize; StorageLive(_3); +- _3 = OffsetOf(Alpha, [(0, 2), (0, 0)]); ++ _3 = const 2_usize; StorageLive(_4); -- _4 = OffsetOf(Alpha, [(0, 1)]); -- _3 = must_use::(move _4) -> [return: bb2, unwind continue]; -+ _4 = const 0_usize; -+ _3 = must_use::(const 0_usize) -> [return: bb2, unwind continue]; - } - - bb2: { - StorageDead(_4); - StorageLive(_5); - StorageLive(_6); -- _6 = OffsetOf(Alpha, [(0, 2), (0, 0)]); -- _5 = must_use::(move _6) -> [return: bb3, unwind continue]; -+ _6 = const 2_usize; -+ _5 = must_use::(const 2_usize) -> [return: bb3, unwind continue]; - } - - bb3: { - StorageDead(_6); - StorageLive(_7); - StorageLive(_8); -- _8 = OffsetOf(Alpha, [(0, 2), (0, 1)]); -- _7 = must_use::(move _8) -> [return: bb4, unwind continue]; -+ _8 = const 3_usize; -+ _7 = must_use::(const 3_usize) -> [return: bb4, unwind continue]; - } - - bb4: { - StorageDead(_8); +- _4 = OffsetOf(Alpha, [(0, 2), (0, 1)]); ++ _4 = const 3_usize; _0 = const (); - StorageDead(_7); - StorageDead(_5); + StorageDead(_4); StorageDead(_3); + StorageDead(_2); StorageDead(_1); return; } diff --git a/tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-abort.diff index 7f166e4fa356..c6908166defb 100644 --- a/tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-abort.diff @@ -4,21 +4,17 @@ fn generic() -> () { let mut _0: (); let _1: usize; - let mut _2: usize; - let mut _4: usize; - let mut _6: usize; - let mut _8: usize; scope 1 { debug gx => _1; - let _3: usize; + let _2: usize; scope 2 { - debug gy => _3; - let _5: usize; + debug gy => _2; + let _3: usize; scope 3 { - debug dx => _5; - let _7: usize; + debug dx => _3; + let _4: usize; scope 4 { - debug dy => _7; + debug dy => _4; } } } @@ -26,45 +22,19 @@ bb0: { StorageLive(_1); + _1 = OffsetOf(Gamma, [(0, 0)]); StorageLive(_2); - _2 = OffsetOf(Gamma, [(0, 0)]); - _1 = must_use::(move _2) -> [return: bb1, unwind unreachable]; - } - - bb1: { - StorageDead(_2); + _2 = OffsetOf(Gamma, [(0, 1)]); StorageLive(_3); +- _3 = OffsetOf(Delta, [(0, 1)]); ++ _3 = const 0_usize; StorageLive(_4); - _4 = OffsetOf(Gamma, [(0, 1)]); - _3 = must_use::(move _4) -> [return: bb2, unwind unreachable]; - } - - bb2: { - StorageDead(_4); - StorageLive(_5); - StorageLive(_6); -- _6 = OffsetOf(Delta, [(0, 1)]); -- _5 = must_use::(move _6) -> [return: bb3, unwind unreachable]; -+ _6 = const 0_usize; -+ _5 = must_use::(const 0_usize) -> [return: bb3, unwind unreachable]; - } - - bb3: { - StorageDead(_6); - StorageLive(_7); - StorageLive(_8); -- _8 = OffsetOf(Delta, [(0, 2)]); -- _7 = must_use::(move _8) -> [return: bb4, unwind unreachable]; -+ _8 = const 2_usize; -+ _7 = must_use::(const 2_usize) -> [return: bb4, unwind unreachable]; - } - - bb4: { - StorageDead(_8); +- _4 = OffsetOf(Delta, [(0, 2)]); ++ _4 = const 2_usize; _0 = const (); - StorageDead(_7); - StorageDead(_5); + StorageDead(_4); StorageDead(_3); + StorageDead(_2); StorageDead(_1); return; } diff --git a/tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-unwind.diff index 38ad6f798016..c6908166defb 100644 --- a/tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/offset_of.generic.DataflowConstProp.panic-unwind.diff @@ -4,21 +4,17 @@ fn generic() -> () { let mut _0: (); let _1: usize; - let mut _2: usize; - let mut _4: usize; - let mut _6: usize; - let mut _8: usize; scope 1 { debug gx => _1; - let _3: usize; + let _2: usize; scope 2 { - debug gy => _3; - let _5: usize; + debug gy => _2; + let _3: usize; scope 3 { - debug dx => _5; - let _7: usize; + debug dx => _3; + let _4: usize; scope 4 { - debug dy => _7; + debug dy => _4; } } } @@ -26,45 +22,19 @@ bb0: { StorageLive(_1); + _1 = OffsetOf(Gamma, [(0, 0)]); StorageLive(_2); - _2 = OffsetOf(Gamma, [(0, 0)]); - _1 = must_use::(move _2) -> [return: bb1, unwind continue]; - } - - bb1: { - StorageDead(_2); + _2 = OffsetOf(Gamma, [(0, 1)]); StorageLive(_3); +- _3 = OffsetOf(Delta, [(0, 1)]); ++ _3 = const 0_usize; StorageLive(_4); - _4 = OffsetOf(Gamma, [(0, 1)]); - _3 = must_use::(move _4) -> [return: bb2, unwind continue]; - } - - bb2: { - StorageDead(_4); - StorageLive(_5); - StorageLive(_6); -- _6 = OffsetOf(Delta, [(0, 1)]); -- _5 = must_use::(move _6) -> [return: bb3, unwind continue]; -+ _6 = const 0_usize; -+ _5 = must_use::(const 0_usize) -> [return: bb3, unwind continue]; - } - - bb3: { - StorageDead(_6); - StorageLive(_7); - StorageLive(_8); -- _8 = OffsetOf(Delta, [(0, 2)]); -- _7 = must_use::(move _8) -> [return: bb4, unwind continue]; -+ _8 = const 2_usize; -+ _7 = must_use::(const 2_usize) -> [return: bb4, unwind continue]; - } - - bb4: { - StorageDead(_8); +- _4 = OffsetOf(Delta, [(0, 2)]); ++ _4 = const 2_usize; _0 = const (); - StorageDead(_7); - StorageDead(_5); + StorageDead(_4); StorageDead(_3); + StorageDead(_2); StorageDead(_1); return; } diff --git a/tests/mir-opt/dataflow-const-prop/offset_of.rs b/tests/mir-opt/dataflow-const-prop/offset_of.rs index cd4e1f6990db..12396b31ed0e 100644 --- a/tests/mir-opt/dataflow-const-prop/offset_of.rs +++ b/tests/mir-opt/dataflow-const-prop/offset_of.rs @@ -36,16 +36,16 @@ fn concrete() { // CHECK: debug z0 => [[z0:_.*]]; // CHECK: debug z1 => [[z1:_.*]]; - // CHECK: [[x]] = must_use::(const 4_usize) -> {{.*}} + // CHECK: [[x]] = const 4_usize let x = offset_of!(Alpha, x); - // CHECK: [[y]] = must_use::(const 0_usize) -> {{.*}} + // CHECK: [[y]] = const 0_usize let y = offset_of!(Alpha, y); - // CHECK: [[z0]] = must_use::(const 2_usize) -> {{.*}} + // CHECK: [[z0]] = const 2_usize let z0 = offset_of!(Alpha, z.0); - // CHECK: [[z1]] = must_use::(const 3_usize) -> {{.*}} + // CHECK: [[z1]] = const 3_usize let z1 = offset_of!(Alpha, z.1); } @@ -58,16 +58,16 @@ fn generic() { // CHECK: debug dx => [[dx:_.*]]; // CHECK: debug dy => [[dy:_.*]]; - // CHECK: [[gx]] = must_use::(move {{_.*}}) -> {{.*}} + // CHECK: [[gx]] = OffsetOf(Gamma, [(0, 0)]); let gx = offset_of!(Gamma, x); - // CHECK: [[gy]] = must_use::(move {{_.*}}) -> {{.*}} + // CHECK: [[gy]] = OffsetOf(Gamma, [(0, 1)]); let gy = offset_of!(Gamma, y); - // CHECK: [[dx]] = must_use::(const 0_usize) -> {{.*}} + // CHECK: [[dx]] = const 0_usize let dx = offset_of!(Delta, x); - // CHECK: [[dy]] = must_use::(const 2_usize) -> {{.*}} + // CHECK: [[dy]] = const 2_usize let dy = offset_of!(Delta, y); } diff --git a/tests/ui/offset-of/offset-of-self.rs b/tests/ui/offset-of/offset-of-self.rs index 51b1a0b24273..1558e13b5309 100644 --- a/tests/ui/offset-of/offset-of-self.rs +++ b/tests/ui/offset-of/offset-of-self.rs @@ -23,9 +23,8 @@ impl S { fn offs_in_c() -> usize { offset_of!(C, w) } - // Put offset_of in a slice - test #124478. - fn offs_in_c_colon() -> &'static [usize] { - &[offset_of!(C::, w)] + fn offs_in_c_colon() -> usize { + offset_of!(C::, w) } } diff --git a/tests/ui/offset-of/offset-of-self.stderr b/tests/ui/offset-of/offset-of-self.stderr index a2104a438ad8..7c7576e066b6 100644 --- a/tests/ui/offset-of/offset-of-self.stderr +++ b/tests/ui/offset-of/offset-of-self.stderr @@ -5,7 +5,7 @@ LL | offset_of!(Self, Self::v); | ^^^^^^^ error[E0412]: cannot find type `S` in module `self` - --> $DIR/offset-of-self.rs:35:26 + --> $DIR/offset-of-self.rs:34:26 | LL | offset_of!(self::S, v); | ^ not found in `self` @@ -21,7 +21,7 @@ LL + offset_of!(S, v); | error[E0411]: cannot find type `Self` in this scope - --> $DIR/offset-of-self.rs:52:16 + --> $DIR/offset-of-self.rs:51:16 | LL | fn main() { | ---- `Self` not allowed in a function @@ -38,13 +38,13 @@ LL | offset_of!(S, Self); = note: available fields are: `v`, `w` error[E0616]: field `v` of struct `T` is private - --> $DIR/offset-of-self.rs:41:30 + --> $DIR/offset-of-self.rs:40:30 | LL | offset_of!(Self, v) | ^ private field error[E0609]: no field `self` on type `S` - --> $DIR/offset-of-self.rs:54:19 + --> $DIR/offset-of-self.rs:53:19 | LL | offset_of!(S, self); | ^^^^ @@ -52,7 +52,7 @@ LL | offset_of!(S, self); = note: available fields are: `v`, `w` error[E0609]: no field `self` on type `u8` - --> $DIR/offset-of-self.rs:55:21 + --> $DIR/offset-of-self.rs:54:21 | LL | offset_of!(S, v.self); | ^^^^ diff --git a/tests/ui/offset-of/offset-of-temporaries.rs b/tests/ui/offset-of/offset-of-temporaries.rs new file mode 100644 index 000000000000..951a8ee2b503 --- /dev/null +++ b/tests/ui/offset-of/offset-of-temporaries.rs @@ -0,0 +1,23 @@ +//@ build-pass + +//! Regression test #124478. + +use std::mem::offset_of; + +struct S { + v: u8, + w: u16, +} + +impl S { + fn return_static_slice() -> &'static [usize] { + &[offset_of!(Self, v), offset_of!(Self, w)] + } + fn use_reference() -> usize { + let r = &offset_of!(Self, v); + *r * 6 + } +} + +fn main() { +} From f9f3573b62107983c22b27dae40d275930f31d4c Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 28 Apr 2024 22:34:51 +0200 Subject: [PATCH 136/279] Fix posix_spawn not being used on iOS and visionOS `man posix_spawn` documents it to be able to return `ENOENT`, and there should be nothing preventing this. Tested in the iOS simulator and on Mac Catalyst. --- library/std/src/sys/pal/unix/process/process_unix.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index 0ce09c90bbd9..f2947161cd56 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -420,13 +420,11 @@ impl Command { } #[cfg(not(any( - target_os = "macos", - target_os = "tvos", - target_os = "watchos", target_os = "freebsd", all(target_os = "linux", target_env = "gnu"), all(target_os = "linux", target_env = "musl"), target_os = "nto", + target_vendor = "apple", )))] fn posix_spawn( &mut self, @@ -439,14 +437,11 @@ impl Command { // Only support platforms for which posix_spawn() can return ENOENT // directly. #[cfg(any( - target_os = "macos", - // FIXME: `target_os = "ios"`? - target_os = "tvos", - target_os = "watchos", target_os = "freebsd", all(target_os = "linux", target_env = "gnu"), all(target_os = "linux", target_env = "musl"), target_os = "nto", + target_vendor = "apple", ))] fn posix_spawn( &mut self, @@ -530,7 +525,7 @@ impl Command { } let addchdir = match self.get_cwd() { Some(cwd) => { - if cfg!(any(target_os = "macos", target_os = "tvos", target_os = "watchos")) { + if cfg!(target_vendor = "apple") { // There is a bug in macOS where a relative executable // path like "../myprogram" will cause `posix_spawn` to // successfully launch the program, but erroneously return From 8aa3c5975253c5795e2f20e200f6d45b0e18de7f Mon Sep 17 00:00:00 2001 From: George Bateman Date: Sun, 28 Apr 2024 21:38:55 +0100 Subject: [PATCH 137/279] Move rustfmt changes out Now in https://github.com/rust-lang/rustfmt/pull/6154 --- Cargo.lock | 1 + src/tools/rustfmt/Cargo.toml | 1 + src/tools/rustfmt/src/comment.rs | 20 ++++++++++++----- src/tools/rustfmt/src/lib.rs | 10 +++------ .../rustfmt/src/test/configuration_snippet.rs | 22 +++++++++++++------ 5 files changed, 34 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 233f4af1e24b..900c12f1641b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4884,6 +4884,7 @@ dependencies = [ "getopts", "ignore", "itertools 0.11.0", + "lazy_static", "regex", "rustfmt-config_proc_macro", "serde", diff --git a/src/tools/rustfmt/Cargo.toml b/src/tools/rustfmt/Cargo.toml index b18c80654a07..032b9b548104 100644 --- a/src/tools/rustfmt/Cargo.toml +++ b/src/tools/rustfmt/Cargo.toml @@ -44,6 +44,7 @@ dirs = "4.0" getopts = "0.2" ignore = "0.4" itertools = "0.11" +lazy_static = "1.4" regex = "1.7" serde = { version = "1.0.160", features = ["derive"] } serde_json = "1.0" diff --git a/src/tools/rustfmt/src/comment.rs b/src/tools/rustfmt/src/comment.rs index 099e12f86dd2..7d1b0384431b 100644 --- a/src/tools/rustfmt/src/comment.rs +++ b/src/tools/rustfmt/src/comment.rs @@ -3,6 +3,8 @@ use std::{borrow::Cow, iter}; use itertools::{multipeek, MultiPeek}; +use lazy_static::lazy_static; +use regex::Regex; use rustc_span::Span; use crate::config::Config; @@ -15,6 +17,17 @@ use crate::utils::{ }; use crate::{ErrorKind, FormattingError}; +lazy_static! { + /// A regex matching reference doc links. + /// + /// ```markdown + /// /// An [example]. + /// /// + /// /// [example]: this::is::a::link + /// ``` + static ref REFERENCE_LINK_URL: Regex = Regex::new(r"^\[.+\]\s?:").unwrap(); +} + fn is_custom_comment(comment: &str) -> bool { if !comment.starts_with("//") { false @@ -967,16 +980,11 @@ fn trim_custom_comment_prefix(s: &str) -> String { /// Returns `true` if the given string MAY include URLs or alike. fn has_url(s: &str) -> bool { // This function may return false positive, but should get its job done in most cases. - // The regex is indended to capture text such as the below. - // - // /// An [example]. - // /// - // /// [example]: this::is::a::link s.contains("https://") || s.contains("http://") || s.contains("ftp://") || s.contains("file://") - || static_regex!(r"^\[.+\]\s?:").is_match(s) + || REFERENCE_LINK_URL.is_match(s) } /// Returns true if the given string may be part of a Markdown table. diff --git a/src/tools/rustfmt/src/lib.rs b/src/tools/rustfmt/src/lib.rs index e07720f30ca5..877d057a34ba 100644 --- a/src/tools/rustfmt/src/lib.rs +++ b/src/tools/rustfmt/src/lib.rs @@ -5,6 +5,9 @@ #![allow(clippy::match_like_matches_macro)] #![allow(unreachable_pub)] +#[cfg(test)] +#[macro_use] +extern crate lazy_static; #[macro_use] extern crate tracing; @@ -59,13 +62,6 @@ pub use crate::rustfmt_diff::{ModifiedChunk, ModifiedLines}; #[macro_use] mod utils; -macro_rules! static_regex { - ($re:literal) => {{ - static RE: ::std::sync::OnceLock<::regex::Regex> = ::std::sync::OnceLock::new(); - RE.get_or_init(|| ::regex::Regex::new($re).unwrap()) - }}; -} - mod attr; mod chains; mod closures; diff --git a/src/tools/rustfmt/src/test/configuration_snippet.rs b/src/tools/rustfmt/src/test/configuration_snippet.rs index a195b306da38..80b61c88a001 100644 --- a/src/tools/rustfmt/src/test/configuration_snippet.rs +++ b/src/tools/rustfmt/src/test/configuration_snippet.rs @@ -24,6 +24,19 @@ impl ConfigurationSection { fn get_section>( file: &mut Enumerate, ) -> Option { + lazy_static! { + static ref CONFIG_NAME_REGEX: regex::Regex = + regex::Regex::new(r"^## `([^`]+)`").expect("failed creating configuration pattern"); + // Configuration values, which will be passed to `from_str`: + // + // - must be prefixed with `####` + // - must be wrapped in backticks + // - may by wrapped in double quotes (which will be stripped) + static ref CONFIG_VALUE_REGEX: regex::Regex = + regex::Regex::new(r#"^#### `"?([^`]+?)"?`"#) + .expect("failed creating configuration value pattern"); + } + loop { match file.next() { Some((i, line)) => { @@ -40,14 +53,9 @@ impl ConfigurationSection { let start_line = (i + 2) as u32; return Some(ConfigurationSection::CodeBlock((block, start_line))); - } else if let Some(c) = static_regex!(r"^## `([^`]+)`").captures(&line) { + } else if let Some(c) = CONFIG_NAME_REGEX.captures(&line) { return Some(ConfigurationSection::ConfigName(String::from(&c[1]))); - } else if let Some(c) = static_regex!(r#"^#### `"?([^`]+?)"?`"#).captures(&line) { - // Configuration values, which will be passed to `from_str` - // - // - must be prefixed with `####` - // - must be wrapped in backticks - // - may by wrapped in double quotes (which will be stripped) + } else if let Some(c) = CONFIG_VALUE_REGEX.captures(&line) { return Some(ConfigurationSection::ConfigValue(String::from(&c[1]))); } } From e0f8202ed5828670ac5125d3db2adbfb516cca3d Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 28 Apr 2024 15:27:36 -0500 Subject: [PATCH 138/279] Stabilize `non_null_convenience` Fully stabilize the following API, including const where applicable: impl NonNull { pub const unsafe fn offset(self, count: isize) -> Self; pub const unsafe fn add(self, count: usize) -> Self; pub const unsafe fn sub(self, count: usize) -> Self; pub const unsafe fn offset_from(self, origin: NonNull) -> isize; pub const unsafe fn read(self) -> T; pub unsafe fn read_volatile(self) -> T; pub const unsafe fn read_unaligned(self) -> T; pub unsafe fn write_volatile(self, val: T); pub unsafe fn replace(self, src: T) -> T; } impl NonNull { pub const unsafe fn byte_offset(self, count: isize) -> Self; pub const unsafe fn byte_add(self, count: usize) -> Self; pub const unsafe fn byte_sub(self, count: usize) -> Self; pub const unsafe fn byte_offset_from(self, origin: NonNull) -> isize; pub unsafe fn drop_in_place(self); } Stabilize the following without const: impl NonNull { // const under `const_intrinsic_copy` pub const unsafe fn copy_to(self, dest: NonNull, count: usize); pub const unsafe fn copy_to_nonoverlapping(self, dest: NonNull, count: usize); pub const unsafe fn copy_from(self, src: NonNull, count: usize); pub const unsafe fn copy_from_nonoverlapping(self, src: NonNull, count: usize); // const under `const_ptr_write` pub const unsafe fn write(self, val: T); pub const unsafe fn write_bytes(self, val: u8, count: usize); pub const unsafe fn write_unaligned(self, val: T); // const under `const_swap` pub const unsafe fn swap(self, with: NonNull); // const under `const_align_offset` pub const fn align_offset(self, align: usize) -> usize; // const under `const_pointer_is_aligned` pub const fn is_aligned(self) -> bool; } Left the following unstable: impl NonNull { // moved gate to `ptr_sub_ptr` pub const unsafe fn sub_ptr(self, subtracted: NonNull) -> usize; } impl NonNull { // moved gate to `pointer_is_aligned_to` pub const fn is_aligned_to(self, align: usize) -> bool; } Fixes: https://github.com/rust-lang/rust/issues/117691 --- library/alloc/src/lib.rs | 1 - library/core/src/lib.rs | 1 - library/core/src/ptr/non_null.rs | 140 ++++++++++++++----------------- 3 files changed, 63 insertions(+), 79 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 2bd8fca7e01b..4e8792f6fb99 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -137,7 +137,6 @@ #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_uninit_array)] #![feature(maybe_uninit_uninit_array_transpose)] -#![feature(non_null_convenience)] #![feature(panic_internals)] #![feature(pattern)] #![feature(ptr_internals)] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 19e0ce7099d1..cee3870c6292 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -180,7 +180,6 @@ #![feature(isqrt)] #![feature(link_cfg)] #![feature(maybe_uninit_uninit_array)] -#![feature(non_null_convenience)] #![feature(offset_of_enum)] #![feature(offset_of_nested)] #![feature(panic_internals)] diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 96ce3cd3a3fb..8697b22278f8 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -512,7 +512,6 @@ impl NonNull { /// # Examples /// /// ``` - /// #![feature(non_null_convenience)] /// use std::ptr::NonNull; /// /// let mut s = [1, 2, 3]; @@ -523,12 +522,12 @@ impl NonNull { /// println!("{}", ptr.offset(2).read()); /// } /// ``` - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] - #[must_use = "returns a new pointer rather than modifying its argument"] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - pub const unsafe fn offset(self, count: isize) -> NonNull + #[must_use = "returns a new pointer rather than modifying its argument"] + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + pub const unsafe fn offset(self, count: isize) -> Self where T: Sized, { @@ -549,11 +548,11 @@ impl NonNull { /// /// For non-`Sized` pointees this operation changes only the data pointer, /// leaving the metadata untouched. - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] #[must_use] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] pub const unsafe fn byte_offset(self, count: isize) -> Self { // SAFETY: the caller must uphold the safety contract for `offset` and `byte_offset` has // the same safety contract. @@ -599,7 +598,6 @@ impl NonNull { /// # Examples /// /// ``` - /// #![feature(non_null_convenience)] /// use std::ptr::NonNull; /// /// let s: &str = "123"; @@ -610,11 +608,11 @@ impl NonNull { /// println!("{}", ptr.add(2).read() as char); /// } /// ``` - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] - #[must_use = "returns a new pointer rather than modifying its argument"] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[must_use = "returns a new pointer rather than modifying its argument"] + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] pub const unsafe fn add(self, count: usize) -> Self where T: Sized, @@ -636,12 +634,12 @@ impl NonNull { /// /// For non-`Sized` pointees this operation changes only the data pointer, /// leaving the metadata untouched. - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] #[must_use] #[inline(always)] - #[rustc_allow_const_fn_unstable(set_ptr_value)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_allow_const_fn_unstable(set_ptr_value)] + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] pub const unsafe fn byte_add(self, count: usize) -> Self { // SAFETY: the caller must uphold the safety contract for `add` and `byte_add` has the same // safety contract. @@ -688,7 +686,6 @@ impl NonNull { /// # Examples /// /// ``` - /// #![feature(non_null_convenience)] /// use std::ptr::NonNull; /// /// let s: &str = "123"; @@ -699,11 +696,11 @@ impl NonNull { /// println!("{}", end.sub(2).read() as char); /// } /// ``` - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] - #[must_use = "returns a new pointer rather than modifying its argument"] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[must_use = "returns a new pointer rather than modifying its argument"] + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] pub const unsafe fn sub(self, count: usize) -> Self where T: Sized, @@ -730,12 +727,12 @@ impl NonNull { /// /// For non-`Sized` pointees this operation changes only the data pointer, /// leaving the metadata untouched. - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] #[must_use] #[inline(always)] - #[rustc_allow_const_fn_unstable(set_ptr_value)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_allow_const_fn_unstable(set_ptr_value)] + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] pub const unsafe fn byte_sub(self, count: usize) -> Self { // SAFETY: the caller must uphold the safety contract for `sub` and `byte_sub` has the same // safety contract. @@ -816,7 +813,6 @@ impl NonNull { /// Basic usage: /// /// ``` - /// #![feature(non_null_convenience)] /// use std::ptr::NonNull; /// /// let a = [0; 5]; @@ -833,7 +829,7 @@ impl NonNull { /// *Incorrect* usage: /// /// ```rust,no_run - /// #![feature(non_null_convenience, strict_provenance)] + /// #![feature(strict_provenance)] /// use std::ptr::NonNull; /// /// let ptr1 = NonNull::new(Box::into_raw(Box::new(0u8))).unwrap(); @@ -845,14 +841,13 @@ impl NonNull { /// // Since ptr2_other and ptr2 are derived from pointers to different objects, /// // computing their offset is undefined behavior, even though /// // they point to the same address! - /// unsafe { - /// let zero = ptr2_other.offset_from(ptr2); // Undefined Behavior - /// } + /// + /// let zero = unsafe { ptr2_other.offset_from(ptr2) }; // Undefined Behavior /// ``` - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] pub const unsafe fn offset_from(self, origin: NonNull) -> isize where T: Sized, @@ -870,10 +865,10 @@ impl NonNull { /// /// For non-`Sized` pointees this operation considers only the data pointers, /// ignoring the metadata. - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] pub const unsafe fn byte_offset_from(self, origin: NonNull) -> isize { // SAFETY: the caller must uphold the safety contract for `byte_offset_from`. unsafe { self.pointer.byte_offset_from(origin.pointer) } @@ -897,7 +892,7 @@ impl NonNull { /// to [`sub`](#method.sub)). The following are all equivalent, assuming /// that their safety preconditions are met: /// ```rust - /// # #![feature(non_null_convenience)] + /// # #![feature(ptr_sub_ptr)] /// # unsafe fn blah(ptr: std::ptr::NonNull, origin: std::ptr::NonNull, count: usize) -> bool { /// ptr.sub_ptr(origin) == count /// # && @@ -926,7 +921,7 @@ impl NonNull { /// # Examples /// /// ``` - /// #![feature(non_null_convenience)] + /// #![feature(ptr_sub_ptr)] /// use std::ptr::NonNull; /// /// let a = [0; 5]; @@ -942,12 +937,10 @@ impl NonNull { /// // This would be incorrect, as the pointers are not correctly ordered: /// // ptr1.sub_ptr(ptr2) /// ``` - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] - // #[unstable(feature = "ptr_sub_ptr", issue = "95892")] - // #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[unstable(feature = "ptr_sub_ptr", issue = "95892")] + #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] pub const unsafe fn sub_ptr(self, subtracted: NonNull) -> usize where T: Sized, @@ -962,10 +955,10 @@ impl NonNull { /// See [`ptr::read`] for safety concerns and examples. /// /// [`ptr::read`]: crate::ptr::read() - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] pub const unsafe fn read(self) -> T where T: Sized, @@ -984,9 +977,9 @@ impl NonNull { /// See [`ptr::read_volatile`] for safety concerns and examples. /// /// [`ptr::read_volatile`]: crate::ptr::read_volatile() - #[unstable(feature = "non_null_convenience", issue = "117691")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] pub unsafe fn read_volatile(self) -> T where T: Sized, @@ -1003,10 +996,10 @@ impl NonNull { /// See [`ptr::read_unaligned`] for safety concerns and examples. /// /// [`ptr::read_unaligned`]: crate::ptr::read_unaligned() - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] pub const unsafe fn read_unaligned(self) -> T where T: Sized, @@ -1023,10 +1016,10 @@ impl NonNull { /// See [`ptr::copy`] for safety concerns and examples. /// /// [`ptr::copy`]: crate::ptr::copy() - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] pub const unsafe fn copy_to(self, dest: NonNull, count: usize) where T: Sized, @@ -1043,10 +1036,10 @@ impl NonNull { /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples. /// /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping() - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] pub const unsafe fn copy_to_nonoverlapping(self, dest: NonNull, count: usize) where T: Sized, @@ -1063,10 +1056,10 @@ impl NonNull { /// See [`ptr::copy`] for safety concerns and examples. /// /// [`ptr::copy`]: crate::ptr::copy() - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] pub const unsafe fn copy_from(self, src: NonNull, count: usize) where T: Sized, @@ -1083,10 +1076,10 @@ impl NonNull { /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples. /// /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping() - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] pub const unsafe fn copy_from_nonoverlapping(self, src: NonNull, count: usize) where T: Sized, @@ -1100,8 +1093,8 @@ impl NonNull { /// See [`ptr::drop_in_place`] for safety concerns and examples. /// /// [`ptr::drop_in_place`]: crate::ptr::drop_in_place() - #[unstable(feature = "non_null_convenience", issue = "117691")] #[inline(always)] + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] pub unsafe fn drop_in_place(self) { // SAFETY: the caller must uphold the safety contract for `drop_in_place`. unsafe { ptr::drop_in_place(self.as_ptr()) } @@ -1113,11 +1106,10 @@ impl NonNull { /// See [`ptr::write`] for safety concerns and examples. /// /// [`ptr::write`]: crate::ptr::write() - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] - //#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] pub const unsafe fn write(self, val: T) where T: Sized, @@ -1132,12 +1124,11 @@ impl NonNull { /// See [`ptr::write_bytes`] for safety concerns and examples. /// /// [`ptr::write_bytes`]: crate::ptr::write_bytes() - #[doc(alias = "memset")] - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] - //#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] #[inline(always)] + #[doc(alias = "memset")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] pub const unsafe fn write_bytes(self, val: u8, count: usize) where T: Sized, @@ -1156,9 +1147,9 @@ impl NonNull { /// See [`ptr::write_volatile`] for safety concerns and examples. /// /// [`ptr::write_volatile`]: crate::ptr::write_volatile() - #[unstable(feature = "non_null_convenience", issue = "117691")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] pub unsafe fn write_volatile(self, val: T) where T: Sized, @@ -1175,11 +1166,10 @@ impl NonNull { /// See [`ptr::write_unaligned`] for safety concerns and examples. /// /// [`ptr::write_unaligned`]: crate::ptr::write_unaligned() - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] - //#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] pub const unsafe fn write_unaligned(self, val: T) where T: Sized, @@ -1194,8 +1184,8 @@ impl NonNull { /// See [`ptr::replace`] for safety concerns and examples. /// /// [`ptr::replace`]: crate::ptr::replace() - #[unstable(feature = "non_null_convenience", issue = "117691")] #[inline(always)] + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] pub unsafe fn replace(self, src: T) -> T where T: Sized, @@ -1211,10 +1201,9 @@ impl NonNull { /// See [`ptr::swap`] for safety concerns and examples. /// /// [`ptr::swap`]: crate::ptr::swap() - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] - //#[rustc_const_unstable(feature = "const_swap", issue = "83163")] #[inline(always)] + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_unstable(feature = "const_swap", issue = "83163")] pub const unsafe fn swap(self, with: NonNull) where T: Sized, @@ -1246,7 +1235,6 @@ impl NonNull { /// Accessing adjacent `u8` as `u16` /// /// ``` - /// #![feature(non_null_convenience)] /// use std::mem::align_of; /// use std::ptr::NonNull; /// @@ -1264,11 +1252,10 @@ impl NonNull { /// } /// # } /// ``` - #[unstable(feature = "non_null_convenience", issue = "117691")] - #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] - //#[rustc_const_unstable(feature = "const_align_offset", issue = "90962")] - #[must_use] #[inline] + #[must_use] + #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")] pub const fn align_offset(self, align: usize) -> usize where T: Sized, @@ -1312,10 +1299,9 @@ impl NonNull { /// underlying allocation. /// /// ``` - /// #![feature(const_pointer_is_aligned)] - /// #![feature(non_null_convenience)] - /// #![feature(const_option)] /// #![feature(const_nonnull_new)] + /// #![feature(const_option)] + /// #![feature(const_pointer_is_aligned)] /// use std::ptr::NonNull; /// /// // On some platforms, the alignment of primitives is less than their size. @@ -1390,10 +1376,10 @@ impl NonNull { /// ``` /// /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203 + #[inline] + #[must_use] #[stable(feature = "pointer_is_aligned", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")] - #[must_use] - #[inline] pub const fn is_aligned(self) -> bool where T: Sized, @@ -1505,10 +1491,10 @@ impl NonNull { /// ``` /// /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203 + #[inline] + #[must_use] #[unstable(feature = "pointer_is_aligned_to", issue = "96284")] #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")] - #[must_use] - #[inline] pub const fn is_aligned_to(self, align: usize) -> bool { self.pointer.is_aligned_to(align) } From 4814fd0a4bcc2288ba15fb212610bdf3d1d5eb11 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 29 Apr 2024 08:53:45 +1000 Subject: [PATCH 139/279] Remove `extern crate rustc_macros` from numerous crates. --- compiler/rustc_ast/src/ast.rs | 2 +- compiler/rustc_ast/src/expand/allocator.rs | 1 + compiler/rustc_ast/src/expand/mod.rs | 1 + compiler/rustc_ast/src/format.rs | 1 + compiler/rustc_ast/src/lib.rs | 3 --- compiler/rustc_ast/src/token.rs | 2 +- compiler/rustc_ast/src/tokenstream.rs | 2 +- compiler/rustc_ast_ir/src/lib.rs | 3 +-- compiler/rustc_attr/src/builtin.rs | 2 +- compiler/rustc_attr/src/lib.rs | 3 --- compiler/rustc_attr/src/session_diagnostics.rs | 2 +- .../rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs | 3 +++ compiler/rustc_codegen_llvm/src/lib.rs | 2 -- compiler/rustc_codegen_ssa/src/lib.rs | 3 +-- compiler/rustc_data_structures/src/lib.rs | 2 -- compiler/rustc_data_structures/src/sorted_map.rs | 1 + compiler/rustc_data_structures/src/svh.rs | 4 ++-- compiler/rustc_data_structures/src/unord.rs | 1 + compiler/rustc_errors/src/diagnostic.rs | 1 + compiler/rustc_errors/src/diagnostic_impls.rs | 1 + compiler/rustc_errors/src/lib.rs | 4 +--- compiler/rustc_errors/src/snippet.rs | 1 + compiler/rustc_expand/src/errors.rs | 2 +- compiler/rustc_expand/src/lib.rs | 3 --- compiler/rustc_expand/src/mbe.rs | 1 + compiler/rustc_expand/src/mbe/diagnostics.rs | 1 + compiler/rustc_expand/src/mbe/metavar_expr.rs | 1 + compiler/rustc_hir/src/def.rs | 2 +- compiler/rustc_hir/src/definitions.rs | 1 + compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_hir/src/hir_id.rs | 1 + compiler/rustc_hir/src/lang_items.rs | 2 +- compiler/rustc_hir/src/lib.rs | 3 --- compiler/rustc_infer/src/infer/canonical/instantiate.rs | 1 + compiler/rustc_infer/src/infer/error_reporting/mod.rs | 1 + compiler/rustc_infer/src/infer/mod.rs | 5 +++-- compiler/rustc_infer/src/infer/region_constraints/mod.rs | 1 + compiler/rustc_infer/src/lib.rs | 2 -- compiler/rustc_infer/src/traits/engine.rs | 1 + compiler/rustc_lint_defs/src/lib.rs | 4 +--- compiler/rustc_metadata/src/errors.rs | 2 +- compiler/rustc_metadata/src/lib.rs | 2 -- compiler/rustc_metadata/src/rmeta/mod.rs | 2 ++ compiler/rustc_query_system/src/dep_graph/dep_node.rs | 4 ++-- compiler/rustc_query_system/src/dep_graph/graph.rs | 1 + compiler/rustc_query_system/src/lib.rs | 2 -- compiler/rustc_query_system/src/query/mod.rs | 1 + compiler/rustc_session/src/config.rs | 1 + compiler/rustc_session/src/cstore.rs | 1 + compiler/rustc_session/src/errors.rs | 2 +- compiler/rustc_session/src/lib.rs | 2 -- compiler/rustc_session/src/search_paths.rs | 1 + compiler/rustc_session/src/utils.rs | 1 + compiler/rustc_session/src/version.rs | 1 + compiler/rustc_span/src/def_id.rs | 2 +- compiler/rustc_span/src/edition.rs | 2 +- compiler/rustc_span/src/hygiene.rs | 2 +- compiler/rustc_span/src/lib.rs | 5 +---- compiler/rustc_span/src/source_map.rs | 1 + compiler/rustc_span/src/symbol.rs | 2 +- compiler/rustc_target/src/abi/call/mod.rs | 3 +++ compiler/rustc_target/src/asm/aarch64.rs | 1 - compiler/rustc_target/src/asm/arm.rs | 1 - compiler/rustc_target/src/asm/avr.rs | 1 - compiler/rustc_target/src/asm/bpf.rs | 1 - compiler/rustc_target/src/asm/csky.rs | 1 - compiler/rustc_target/src/asm/hexagon.rs | 1 - compiler/rustc_target/src/asm/loongarch.rs | 1 - compiler/rustc_target/src/asm/m68k.rs | 1 - compiler/rustc_target/src/asm/mips.rs | 1 - compiler/rustc_target/src/asm/mod.rs | 6 +++--- compiler/rustc_target/src/asm/msp430.rs | 1 - compiler/rustc_target/src/asm/nvptx.rs | 1 - compiler/rustc_target/src/asm/powerpc.rs | 1 - compiler/rustc_target/src/asm/riscv.rs | 1 - compiler/rustc_target/src/asm/s390x.rs | 1 - compiler/rustc_target/src/asm/spirv.rs | 1 - compiler/rustc_target/src/asm/wasm.rs | 1 - compiler/rustc_target/src/asm/x86.rs | 1 - compiler/rustc_target/src/lib.rs | 3 --- compiler/rustc_target/src/spec/abi/mod.rs | 2 +- compiler/rustc_target/src/spec/mod.rs | 3 +-- compiler/rustc_trait_selection/src/errors.rs | 2 +- compiler/rustc_trait_selection/src/infer.rs | 5 ++--- compiler/rustc_trait_selection/src/lib.rs | 2 -- compiler/rustc_trait_selection/src/regions.rs | 1 + .../src/solve/assembly/structural_traits.rs | 1 + compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs | 1 + .../rustc_trait_selection/src/solve/eval_ctxt/select.rs | 1 + compiler/rustc_trait_selection/src/solve/inspect/analyse.rs | 1 + compiler/rustc_trait_selection/src/solve/mod.rs | 1 + compiler/rustc_trait_selection/src/traits/engine.rs | 1 + .../src/traits/error_reporting/infer_ctxt_ext.rs | 1 + .../src/traits/error_reporting/on_unimplemented.rs | 1 + .../src/traits/error_reporting/suggestions.rs | 1 + .../src/traits/error_reporting/type_err_ctxt_ext.rs | 1 + compiler/rustc_trait_selection/src/traits/normalize.rs | 1 + .../rustc_trait_selection/src/traits/outlives_bounds.rs | 1 + .../src/traits/query/evaluate_obligation.rs | 1 + .../rustc_trait_selection/src/traits/query/normalize.rs | 1 + .../src/traits/query/type_op/implied_outlives_bounds.rs | 1 + .../src/traits/query/type_op/outlives.rs | 1 + .../src/traits/specialize/specialization_graph.rs | 1 + .../src/traits/structural_normalize.rs | 1 + compiler/rustc_type_ir/src/canonical.rs | 2 ++ compiler/rustc_type_ir/src/const_kind.rs | 2 ++ compiler/rustc_type_ir/src/lib.rs | 5 ++--- compiler/rustc_type_ir/src/predicate_kind.rs | 2 ++ compiler/rustc_type_ir/src/region_kind.rs | 2 ++ compiler/rustc_type_ir/src/ty_kind.rs | 2 ++ 110 files changed, 99 insertions(+), 94 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index af246e313718..8eba5af1442b 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -32,7 +32,7 @@ use rustc_data_structures::packed::Pu128; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::sync::Lrc; -use rustc_macros::HashStable_Generic; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::source_map::{respan, Spanned}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP}; diff --git a/compiler/rustc_ast/src/expand/allocator.rs b/compiler/rustc_ast/src/expand/allocator.rs index f825b10f489b..1723501d0fec 100644 --- a/compiler/rustc_ast/src/expand/allocator.rs +++ b/compiler/rustc_ast/src/expand/allocator.rs @@ -1,3 +1,4 @@ +use rustc_macros::HashStable_Generic; use rustc_span::symbol::{sym, Symbol}; #[derive(Clone, Debug, Copy, Eq, PartialEq, HashStable_Generic)] diff --git a/compiler/rustc_ast/src/expand/mod.rs b/compiler/rustc_ast/src/expand/mod.rs index 942347383ce3..37caadd04143 100644 --- a/compiler/rustc_ast/src/expand/mod.rs +++ b/compiler/rustc_ast/src/expand/mod.rs @@ -1,5 +1,6 @@ //! Definitions shared by macros / syntax extensions and e.g. `rustc_middle`. +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::{def_id::DefId, symbol::Ident}; use crate::MetaItem; diff --git a/compiler/rustc_ast/src/format.rs b/compiler/rustc_ast/src/format.rs index 805596ff00a9..49910e2283dd 100644 --- a/compiler/rustc_ast/src/format.rs +++ b/compiler/rustc_ast/src/format.rs @@ -1,6 +1,7 @@ use crate::ptr::P; use crate::Expr; use rustc_data_structures::fx::FxHashMap; +use rustc_macros::{Decodable, Encodable}; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::Span; diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 4f21ff415290..6b665ff72d68 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -20,9 +20,6 @@ #![feature(negative_impls)] #![feature(stmt_expr_attributes)] -#[macro_use] -extern crate rustc_macros; - #[macro_use] extern crate tracing; diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index dcdd44c60416..6e9465307490 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -9,7 +9,7 @@ use crate::util::case::Case; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lrc; -use rustc_macros::HashStable_Generic; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::symbol::{kw, sym}; #[allow(clippy::useless_attribute)] // FIXME: following use of `hidden_glob_reexports` incorrectly triggers `useless_attribute` lint. #[allow(hidden_glob_reexports)] diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 08d65a5ffa58..aadcfa7fed59 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -20,7 +20,7 @@ use crate::AttrVec; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{self, Lrc}; -use rustc_macros::HashStable_Generic; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Encodable}; use rustc_span::{sym, Span, SpanDecoder, SpanEncoder, Symbol, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs index 9ff2e32f06b0..b1a77639b562 100644 --- a/compiler/rustc_ast_ir/src/lib.rs +++ b/compiler/rustc_ast_ir/src/lib.rs @@ -3,8 +3,7 @@ #![cfg_attr(feature = "nightly", allow(internal_features))] #[cfg(feature = "nightly")] -#[macro_use] -extern crate rustc_macros; +use rustc_macros::{Decodable, Encodable, HashStable_NoContext}; pub mod visit; diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 1c2077372e1c..c08bf2877336 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -6,7 +6,7 @@ use rustc_ast::{Attribute, LitKind, MetaItem, MetaItemKind, MetaItemLit, NestedM use rustc_ast_pretty::pprust; use rustc_errors::ErrorGuaranteed; use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg}; -use rustc_macros::HashStable_Generic; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_session::config::ExpectedValues; use rustc_session::lint::builtin::UNEXPECTED_CFGS; use rustc_session::lint::BuiltinLintDiag; diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs index dd87a5c4dc38..c61b7ea6d822 100644 --- a/compiler/rustc_attr/src/lib.rs +++ b/compiler/rustc_attr/src/lib.rs @@ -9,9 +9,6 @@ #![doc(rust_logo)] #![feature(let_chains)] -#[macro_use] -extern crate rustc_macros; - mod builtin; mod session_diagnostics; diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index 0ad7bd6e17e5..303909de3435 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -2,7 +2,7 @@ use std::num::IntErrorKind; use rustc_ast as ast; use rustc_errors::{codes::*, Applicability, Diag, DiagCtxt, Diagnostic, EmissionGuarantee, Level}; -use rustc_macros::Diagnostic; +use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; use crate::fluent_generated as fluent; diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs index 1aec65cf9490..e521d5e259ca 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs @@ -5,6 +5,7 @@ use rustc_data_structures::{ fx::FxHashMap, stable_hasher::{HashStable, StableHasher}, }; +use rustc_macros::HashStable; use rustc_middle::{ bug, ty::{ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt}, @@ -23,6 +24,8 @@ use crate::{ use super::{unknown_file_metadata, SmallVec, UNKNOWN_LINE_NUMBER}; mod private { + use rustc_macros::HashStable; + // This type cannot be constructed outside of this module because // it has a private field. We make use of this in order to prevent // `UniqueTypeId` from being constructed directly, without asserting diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index c84461e53eb1..1cecf682e5db 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -15,8 +15,6 @@ #![feature(let_chains)] #![feature(impl_trait_in_assoc_type)] -#[macro_use] -extern crate rustc_macros; #[macro_use] extern crate tracing; diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 80fe7e0bb786..be91fe8480cd 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -16,8 +16,6 @@ //! The backend-agnostic functions of this crate use functions defined in various traits that //! have to be implemented by each backend. -#[macro_use] -extern crate rustc_macros; #[macro_use] extern crate tracing; #[macro_use] @@ -29,6 +27,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::Lrc; use rustc_data_structures::unord::UnordMap; use rustc_hir::def_id::CrateNum; +use rustc_macros::{Decodable, Encodable, HashStable}; use rustc_middle::dep_graph::WorkProduct; use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile; use rustc_middle::middle::dependency_format::Dependencies; diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 2b799d6f5d3b..495c1977df9d 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -41,8 +41,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_macros; use std::fmt; diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs index 1436628139fd..21d7c91ec482 100644 --- a/compiler/rustc_data_structures/src/sorted_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map.rs @@ -1,4 +1,5 @@ use crate::stable_hasher::{HashStable, StableHasher, StableOrd}; +use rustc_macros::{Decodable_Generic, Encodable_Generic}; use std::borrow::Borrow; use std::fmt::Debug; use std::mem; diff --git a/compiler/rustc_data_structures/src/svh.rs b/compiler/rustc_data_structures/src/svh.rs index 1cfc9fecd47d..38629ea9801d 100644 --- a/compiler/rustc_data_structures/src/svh.rs +++ b/compiler/rustc_data_structures/src/svh.rs @@ -6,9 +6,9 @@ //! compiled from distinct sources. use crate::fingerprint::Fingerprint; -use std::fmt; - use crate::stable_hasher; +use rustc_macros::{Decodable_Generic, Encodable_Generic}; +use std::fmt; #[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable_Generic, Decodable_Generic, Hash)] pub struct Svh { diff --git a/compiler/rustc_data_structures/src/unord.rs b/compiler/rustc_data_structures/src/unord.rs index a99e2062039b..ca66d58c1395 100644 --- a/compiler/rustc_data_structures/src/unord.rs +++ b/compiler/rustc_data_structures/src/unord.rs @@ -3,6 +3,7 @@ //! as required by the query system. use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_macros::{Decodable_Generic, Encodable_Generic}; use std::{ borrow::{Borrow, BorrowMut}, collections::hash_map::Entry, diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 6c84eeaf888d..121c7f821c52 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -7,6 +7,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_error_messages::fluent_value_from_str_list_sep_by_and; use rustc_error_messages::FluentValue; use rustc_lint_defs::{Applicability, LintExpectationId}; +use rustc_macros::{Decodable, Encodable}; use rustc_span::source_map::Spanned; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 2b10fcd8d6ab..b3a1e29f8e2c 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -7,6 +7,7 @@ use crate::{ use rustc_ast as ast; use rustc_ast_pretty::pprust; use rustc_hir as hir; +use rustc_macros::Subdiagnostic; use rustc_span::edition::Edition; use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol}; use rustc_span::Span; diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index adbac80d7ccb..fe94d41e9bee 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -25,9 +25,6 @@ #![feature(yeet_expr)] // tidy-alphabetical-end -#[macro_use] -extern crate rustc_macros; - #[macro_use] extern crate tracing; @@ -64,6 +61,7 @@ use rustc_data_structures::stable_hasher::{Hash128, StableHasher}; use rustc_data_structures::sync::{Lock, Lrc}; use rustc_data_structures::AtomicRef; use rustc_lint_defs::LintExpectationId; +use rustc_macros::{Decodable, Encodable}; use rustc_span::source_map::SourceMap; use rustc_span::{Loc, Span, DUMMY_SP}; use std::backtrace::{Backtrace, BacktraceStatus}; diff --git a/compiler/rustc_errors/src/snippet.rs b/compiler/rustc_errors/src/snippet.rs index b55f78538852..d6119fb41d22 100644 --- a/compiler/rustc_errors/src/snippet.rs +++ b/compiler/rustc_errors/src/snippet.rs @@ -1,6 +1,7 @@ // Code for annotating snippets. use crate::{Level, Loc}; +use rustc_macros::{Decodable, Encodable}; #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)] pub struct Line { diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index db8e4ba07e80..b0563bfdea74 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -1,6 +1,6 @@ use rustc_ast::ast; use rustc_errors::codes::*; -use rustc_macros::Diagnostic; +use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_session::Limit; use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent}; use rustc_span::{Span, Symbol}; diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index c9a3aeedd020..7b2202aee5b3 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -16,9 +16,6 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(internal_features)] -#[macro_use] -extern crate rustc_macros; - #[macro_use] extern crate tracing; diff --git a/compiler/rustc_expand/src/mbe.rs b/compiler/rustc_expand/src/mbe.rs index ca4a1f327adc..bd6a9b7cb07d 100644 --- a/compiler/rustc_expand/src/mbe.rs +++ b/compiler/rustc_expand/src/mbe.rs @@ -14,6 +14,7 @@ pub(crate) mod transcribe; use metavar_expr::MetaVarExpr; use rustc_ast::token::{Delimiter, NonterminalKind, Token, TokenKind}; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan}; +use rustc_macros::{Decodable, Encodable}; use rustc_span::symbol::Ident; use rustc_span::Span; diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index 15193298ccaa..6068b271433b 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -8,6 +8,7 @@ use rustc_ast::token::{self, Token, TokenKind}; use rustc_ast::tokenstream::TokenStream; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, Diag, DiagCtxt, DiagMessage}; +use rustc_macros::Subdiagnostic; use rustc_parse::parser::{Parser, Recovery}; use rustc_span::source_map::SourceMap; use rustc_span::symbol::Ident; diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs index 81e1de5b0954..8239cfd46cbf 100644 --- a/compiler/rustc_expand/src/mbe/metavar_expr.rs +++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs @@ -3,6 +3,7 @@ use rustc_ast::tokenstream::{RefTokenTreeCursor, TokenStream, TokenTree}; use rustc_ast::{LitIntType, LitKind}; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, PResult}; +use rustc_macros::{Decodable, Encodable}; use rustc_session::parse::ParseSess; use rustc_span::symbol::Ident; use rustc_span::Span; diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 37d9b2ffd6ab..649a08b6972f 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -5,7 +5,7 @@ use rustc_ast as ast; use rustc_ast::NodeId; use rustc_data_structures::stable_hasher::ToStableHashKey; use rustc_data_structures::unord::UnordMap; -use rustc_macros::HashStable_Generic; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::kw; diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index cd5da279a262..d2d18d890130 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -11,6 +11,7 @@ use crate::def_path_hash_map::DefPathHashMap; use rustc_data_structures::stable_hasher::{Hash64, StableHasher}; use rustc_data_structures::unord::UnordMap; use rustc_index::IndexVec; +use rustc_macros::{Decodable, Encodable}; use rustc_span::symbol::{kw, sym, Symbol}; use std::fmt::{self, Write}; diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 1646ea50fb0f..5850fbe5c250 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -13,7 +13,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::sorted_map::SortedMap; use rustc_index::IndexVec; -use rustc_macros::HashStable_Generic; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs index 0341a482fa8c..ac4874695070 100644 --- a/compiler/rustc_hir/src/hir_id.rs +++ b/compiler/rustc_hir/src/hir_id.rs @@ -1,5 +1,6 @@ use crate::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_ID}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey}; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::{def_id::DefPathHash, HashStableContext}; use std::fmt::{self, Debug}; diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 6aee1183a106..969ec0dc534e 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -12,7 +12,7 @@ use crate::{MethodKind, Target}; use rustc_ast as ast; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_macros::HashStable_Generic; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index c5c4075c6baa..f3eea54a7add 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -10,9 +10,6 @@ #![feature(variant_count)] #![allow(internal_features)] -#[macro_use] -extern crate rustc_macros; - #[macro_use] extern crate tracing; diff --git a/compiler/rustc_infer/src/infer/canonical/instantiate.rs b/compiler/rustc_infer/src/infer/canonical/instantiate.rs index c8adbf7f57ab..f95cc13623cd 100644 --- a/compiler/rustc_infer/src/infer/canonical/instantiate.rs +++ b/compiler/rustc_infer/src/infer/canonical/instantiate.rs @@ -7,6 +7,7 @@ //! [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html use crate::infer::canonical::{Canonical, CanonicalVarValues}; +use rustc_macros::extension; use rustc_middle::ty::fold::{FnMutDelegate, TypeFoldable}; use rustc_middle::ty::GenericArgKind; use rustc_middle::ty::{self, TyCtxt}; diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 40a9db10956e..635bbca37ecc 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -68,6 +68,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; +use rustc_macros::extension; use rustc_middle::dep_graph::DepContext; use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError}; use rustc_middle::ty::relate::{self, RelateResult, TypeRelation}; diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 81130d691510..e04bb2d84d25 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -4,6 +4,7 @@ pub use lexical_region_resolve::RegionResolutionError; pub use relate::combine::CombineFields; pub use relate::combine::ObligationEmittingRelation; pub use relate::StructurallyRelateAliases; +pub use rustc_macros::{TypeFoldable, TypeVisitable}; pub use rustc_middle::ty::IntVarValue; pub use BoundRegionConversionTime::*; pub use RegionVariableOrigin::*; @@ -20,13 +21,13 @@ use opaque_types::OpaqueTypeStorage; use region_constraints::{GenericKind, VarInfos, VerifyBound}; use region_constraints::{RegionConstraintCollector, RegionConstraintStorage}; use rustc_data_structures::captures::Captures; -use rustc_data_structures::fx::FxIndexMap; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::undo_log::Rollback; use rustc_data_structures::unify as ut; use rustc_errors::{Diag, DiagCtxt, ErrorGuaranteed}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_macros::extension; use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_middle::infer::unify_key::ConstVariableValue; use rustc_middle::infer::unify_key::EffectVarValue; diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 3d6b54721d03..223e6e3d3441 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -11,6 +11,7 @@ use rustc_data_structures::sync::Lrc; use rustc_data_structures::undo_log::UndoLogs; use rustc_data_structures::unify as ut; use rustc_index::IndexVec; +use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::infer::unify_key::{RegionVariableValue, RegionVidKey}; use rustc_middle::ty::ReStatic; use rustc_middle::ty::{self, Ty, TyCtxt}; diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index a5f52420a84b..b857d439cb79 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -30,8 +30,6 @@ #![feature(yeet_expr)] #![recursion_limit = "512"] // For rustdoc -#[macro_use] -extern crate rustc_macros; #[cfg(target_pointer_width = "64")] #[macro_use] extern crate rustc_data_structures; diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index c495810858f7..cb067c7a6600 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -1,6 +1,7 @@ use crate::infer::InferCtxt; use crate::traits::Obligation; use rustc_hir::def_id::DefId; +use rustc_macros::extension; use rustc_middle::ty::{self, ToPredicate, Ty}; use super::FulfillmentError; diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 7f200a7b623d..3673340ec9b4 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -1,6 +1,3 @@ -#[macro_use] -extern crate rustc_macros; - pub use self::Level::*; use rustc_ast::node_id::NodeId; use rustc_ast::{AttrId, Attribute}; @@ -11,6 +8,7 @@ use rustc_data_structures::stable_hasher::{ use rustc_error_messages::{DiagMessage, MultiSpan}; use rustc_hir::HashStableContext; use rustc_hir::HirId; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::edition::Edition; use rustc_span::{sym, symbol::Ident, Span, Symbol}; use rustc_target::spec::abi::Abi; diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index b50ae0577093..e8449d3918b7 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -4,7 +4,7 @@ use std::{ }; use rustc_errors::{codes::*, Diag, DiagCtxt, Diagnostic, EmissionGuarantee, Level}; -use rustc_macros::Diagnostic; +use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_session::config; use rustc_span::{sym, Span, Symbol}; use rustc_target::spec::{PanicStrategy, TargetTriple}; diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 7dd03407bd7c..c8162a1f0eea 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -19,8 +19,6 @@ extern crate proc_macro; -#[macro_use] -extern crate rustc_macros; #[macro_use] extern crate rustc_middle; diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 5b0be8ac230d..c9cb2f5a2405 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -2,6 +2,7 @@ use crate::creader::CrateMetadataRef; use decoder::Metadata; use def_path_hash_map::DefPathHashMapRef; use rustc_data_structures::fx::FxHashMap; +use rustc_macros::{Decodable, Encodable, TyDecodable, TyEncodable}; use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile; use rustc_middle::middle::lib_features::FeatureStability; use table::TableBuilder; @@ -17,6 +18,7 @@ use rustc_hir::definitions::DefKey; use rustc_hir::lang_items::LangItem; use rustc_index::bit_set::BitSet; use rustc_index::IndexVec; +use rustc_macros::{MetadataDecodable, MetadataEncodable}; use rustc_middle::metadata::ModChild; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs index 17f96896a504..9c196093f231 100644 --- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs +++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs @@ -49,6 +49,7 @@ use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey}; use rustc_data_structures::AtomicRef; use rustc_hir::definitions::DefPathHash; +use rustc_macros::{Decodable, Encodable}; use std::fmt; use std::hash::Hash; @@ -285,8 +286,7 @@ pub struct DepKindStruct { /// some independent path or string that persists between runs without /// the need to be mapped or unmapped. (This ensures we can serialize /// them even in the absence of a tcx.) -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[derive(Encodable, Decodable)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] pub struct WorkProductId { hash: Fingerprint, } diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 2b3fa7f6cfad..3e4e2e919fba 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -6,6 +6,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc}; use rustc_data_structures::unord::UnordMap; use rustc_index::IndexVec; +use rustc_macros::{Decodable, Encodable}; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; use std::assert_matches::assert_matches; use std::collections::hash_map::Entry; diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index 416f556f57d2..e1743b147d4d 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -9,8 +9,6 @@ extern crate tracing; #[macro_use] extern crate rustc_data_structures; -#[macro_use] -extern crate rustc_macros; pub mod cache; pub mod dep_graph; diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 91a0026f281e..ab4f48fcd320 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -20,6 +20,7 @@ use rustc_data_structures::stable_hasher::Hash64; use rustc_data_structures::sync::Lock; use rustc_errors::DiagInner; use rustc_hir::def::DefKind; +use rustc_macros::{Decodable, Encodable}; use rustc_span::def_id::DefId; use rustc_span::Span; use thin_vec::ThinVec; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 4f259960ac3a..b0d9b7c7b00b 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -15,6 +15,7 @@ use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey}; use rustc_errors::emitter::HumanReadableErrorType; use rustc_errors::{ColorConfig, DiagArgValue, DiagCtxtFlags, IntoDiagArg}; use rustc_feature::UnstableFeatures; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION}; use rustc_span::source_map::FilePathMapping; use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm}; diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index 83377b66095d..2c20c3f0e1a3 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -10,6 +10,7 @@ use rustc_hir::def_id::{ CrateNum, DefId, LocalDefId, StableCrateId, StableCrateIdMap, LOCAL_CRATE, }; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions}; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::symbol::Symbol; use rustc_span::Span; use rustc_target::spec::abi::Abi; diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 2e4c7d14ecdf..dce56382a53a 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -6,7 +6,7 @@ use rustc_errors::{ codes::*, Diag, DiagCtxt, DiagMessage, Diagnostic, EmissionGuarantee, ErrorGuaranteed, Level, MultiSpan, }; -use rustc_macros::Diagnostic; +use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple}; diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 58e1394c0907..db52968e8a87 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -6,8 +6,6 @@ #![feature(iter_intersperse)] #![allow(internal_features)] -#[macro_use] -extern crate rustc_macros; pub mod errors; #[macro_use] diff --git a/compiler/rustc_session/src/search_paths.rs b/compiler/rustc_session/src/search_paths.rs index bc2f2a8af1fa..5e8adffc249e 100644 --- a/compiler/rustc_session/src/search_paths.rs +++ b/compiler/rustc_session/src/search_paths.rs @@ -1,5 +1,6 @@ use crate::filesearch::make_target_lib_path; use crate::EarlyDiagCtxt; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_target::spec::TargetTriple; use std::path::{Path, PathBuf}; diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs index 58de5cb31a51..f70a53eeb410 100644 --- a/compiler/rustc_session/src/utils.rs +++ b/compiler/rustc_session/src/utils.rs @@ -1,6 +1,7 @@ use crate::session::Session; use rustc_data_structures::profiling::VerboseTimingGuard; use rustc_fs_util::try_canonicalize; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use std::{ path::{Path, PathBuf}, sync::OnceLock, diff --git a/compiler/rustc_session/src/version.rs b/compiler/rustc_session/src/version.rs index c0c088bcef7d..39e4541349ec 100644 --- a/compiler/rustc_session/src/version.rs +++ b/compiler/rustc_session/src/version.rs @@ -1,3 +1,4 @@ +use rustc_macros::{current_rustc_version, Decodable, Encodable, HashStable_Generic}; use std::fmt::{self, Display}; #[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 8925b7a42d48..1ac3a817bba5 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -6,7 +6,7 @@ use rustc_data_structures::stable_hasher::{ use rustc_data_structures::unhash::Unhasher; use rustc_data_structures::AtomicRef; use rustc_index::Idx; -use rustc_macros::HashStable_Generic; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Encodable}; use std::fmt; use std::hash::{BuildHasherDefault, Hash, Hasher}; diff --git a/compiler/rustc_span/src/edition.rs b/compiler/rustc_span/src/edition.rs index 78ac61fa31db..fe09daf522c1 100644 --- a/compiler/rustc_span/src/edition.rs +++ b/compiler/rustc_span/src/edition.rs @@ -1,7 +1,7 @@ use std::fmt; use std::str::FromStr; -use rustc_macros::HashStable_Generic; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; /// The edition of the compiler. (See [RFC 2052](https://github.com/rust-lang/rfcs/blob/master/text/2052-epochs.md).) #[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, Encodable, Decodable, Eq)] diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 6093df941793..aa4bcefab939 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -34,7 +34,7 @@ use rustc_data_structures::stable_hasher::{Hash64, HashStable, HashingControls, use rustc_data_structures::sync::{Lock, Lrc, WorkerLocal}; use rustc_data_structures::unhash::UnhashMap; use rustc_index::IndexVec; -use rustc_macros::HashStable_Generic; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::cell::RefCell; use std::collections::hash_map::Entry; diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index f749d4eb8336..f83bacdcebe7 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -35,14 +35,11 @@ extern crate self as rustc_span; -#[macro_use] -extern crate rustc_macros; - #[macro_use] extern crate tracing; use rustc_data_structures::{outline, AtomicRef}; -use rustc_macros::HashStable_Generic; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_serialize::opaque::{FileEncoder, MemDecoder}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 33bd11cc807f..2093dcf0e831 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -12,6 +12,7 @@ use crate::*; use rustc_data_structures::sync::{IntoDynSyncSend, MappedReadGuard, ReadGuard, RwLock}; use rustc_data_structures::unhash::UnhashMap; +use rustc_macros::{Decodable, Encodable}; use std::fs; use std::io::{self, BorrowedBuf, Read}; use std::path; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 99591b5e1440..8d38867ab1f9 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -8,7 +8,7 @@ use rustc_data_structures::stable_hasher::{ HashStable, StableCompare, StableHasher, ToStableHashKey, }; use rustc_data_structures::sync::Lock; -use rustc_macros::HashStable_Generic; +use rustc_macros::{symbols, Decodable, Encodable, HashStable_Generic}; use std::fmt; use std::hash::{Hash, Hasher}; diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index cdd82aa9dbc9..3ddea42f67bb 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -1,6 +1,7 @@ use crate::abi::{self, Abi, Align, FieldsShape, Size}; use crate::abi::{HasDataLayout, TyAbiInterface, TyAndLayout}; use crate::spec::{self, HasTargetSpec, HasWasmCAbiOpt}; +use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; use std::str::FromStr; @@ -100,6 +101,8 @@ pub use attr_impl::ArgAttribute; #[allow(non_upper_case_globals)] #[allow(unused)] mod attr_impl { + use rustc_macros::HashStable_Generic; + // The subset of llvm::Attribute needed for arguments, packed into a bitfield. #[derive(Clone, Copy, Default, Hash, PartialEq, Eq, HashStable_Generic)] pub struct ArgAttribute(u8); diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs index 5ae9a2e20581..1a3218da1af0 100644 --- a/compiler/rustc_target/src/asm/aarch64.rs +++ b/compiler/rustc_target/src/asm/aarch64.rs @@ -1,7 +1,6 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; use crate::spec::{RelocModel, Target}; use rustc_data_structures::fx::FxIndexSet; -use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs index f56dbac708b6..37184393a730 100644 --- a/compiler/rustc_target/src/asm/arm.rs +++ b/compiler/rustc_target/src/asm/arm.rs @@ -1,7 +1,6 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; use crate::spec::{RelocModel, Target}; use rustc_data_structures::fx::FxIndexSet; -use rustc_macros::HashStable_Generic; use rustc_span::{sym, Symbol}; use std::fmt; diff --git a/compiler/rustc_target/src/asm/avr.rs b/compiler/rustc_target/src/asm/avr.rs index eab38a4a4f4a..6943fd9b5d72 100644 --- a/compiler/rustc_target/src/asm/avr.rs +++ b/compiler/rustc_target/src/asm/avr.rs @@ -1,5 +1,4 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; -use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; diff --git a/compiler/rustc_target/src/asm/bpf.rs b/compiler/rustc_target/src/asm/bpf.rs index 9bc94274675d..faaeabb3c901 100644 --- a/compiler/rustc_target/src/asm/bpf.rs +++ b/compiler/rustc_target/src/asm/bpf.rs @@ -1,5 +1,4 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; -use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; diff --git a/compiler/rustc_target/src/asm/csky.rs b/compiler/rustc_target/src/asm/csky.rs index 64607ee4b81d..db6cdecfe190 100644 --- a/compiler/rustc_target/src/asm/csky.rs +++ b/compiler/rustc_target/src/asm/csky.rs @@ -1,5 +1,4 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; -use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; diff --git a/compiler/rustc_target/src/asm/hexagon.rs b/compiler/rustc_target/src/asm/hexagon.rs index 19da7b808485..7a809efee6f4 100644 --- a/compiler/rustc_target/src/asm/hexagon.rs +++ b/compiler/rustc_target/src/asm/hexagon.rs @@ -1,5 +1,4 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; -use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; diff --git a/compiler/rustc_target/src/asm/loongarch.rs b/compiler/rustc_target/src/asm/loongarch.rs index 15d0f54ce3b6..534b696f7edf 100644 --- a/compiler/rustc_target/src/asm/loongarch.rs +++ b/compiler/rustc_target/src/asm/loongarch.rs @@ -1,5 +1,4 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; -use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; diff --git a/compiler/rustc_target/src/asm/m68k.rs b/compiler/rustc_target/src/asm/m68k.rs index ac94dcc03dc6..ea367e3d2f94 100644 --- a/compiler/rustc_target/src/asm/m68k.rs +++ b/compiler/rustc_target/src/asm/m68k.rs @@ -1,5 +1,4 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; -use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; diff --git a/compiler/rustc_target/src/asm/mips.rs b/compiler/rustc_target/src/asm/mips.rs index 0ac1a43ae183..f0d659c9b979 100644 --- a/compiler/rustc_target/src/asm/mips.rs +++ b/compiler/rustc_target/src/asm/mips.rs @@ -1,5 +1,4 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; -use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 49de92b86cb4..5f4ce5ed5997 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -1,7 +1,7 @@ use crate::spec::Target; use crate::{abi::Size, spec::RelocModel}; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; -use rustc_macros::HashStable_Generic; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::Symbol; use std::fmt; use std::str::FromStr; @@ -24,7 +24,7 @@ macro_rules! def_reg_class { $class:ident, )* }) => { - #[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, PartialOrd, Hash, HashStable_Generic)] + #[derive(Copy, Clone, rustc_macros::Encodable, rustc_macros::Decodable, Debug, Eq, PartialEq, PartialOrd, Hash, rustc_macros::HashStable_Generic)] #[allow(non_camel_case_types)] pub enum $arch_regclass { $($class,)* @@ -73,7 +73,7 @@ macro_rules! def_regs { )* }) => { #[allow(unreachable_code)] - #[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, PartialOrd, Hash, HashStable_Generic)] + #[derive(Copy, Clone, rustc_macros::Encodable, rustc_macros::Decodable, Debug, Eq, PartialEq, PartialOrd, Hash, rustc_macros::HashStable_Generic)] #[allow(non_camel_case_types)] pub enum $arch_reg { $($reg,)* diff --git a/compiler/rustc_target/src/asm/msp430.rs b/compiler/rustc_target/src/asm/msp430.rs index 439f3ba0b575..14013cd8a7b4 100644 --- a/compiler/rustc_target/src/asm/msp430.rs +++ b/compiler/rustc_target/src/asm/msp430.rs @@ -1,5 +1,4 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; -use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; diff --git a/compiler/rustc_target/src/asm/nvptx.rs b/compiler/rustc_target/src/asm/nvptx.rs index 57aa50fceb88..6c066ad7ac8f 100644 --- a/compiler/rustc_target/src/asm/nvptx.rs +++ b/compiler/rustc_target/src/asm/nvptx.rs @@ -1,5 +1,4 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; -use rustc_macros::HashStable_Generic; use rustc_span::Symbol; def_reg_class! { diff --git a/compiler/rustc_target/src/asm/powerpc.rs b/compiler/rustc_target/src/asm/powerpc.rs index 4e8cbe34de94..45e9ace0f291 100644 --- a/compiler/rustc_target/src/asm/powerpc.rs +++ b/compiler/rustc_target/src/asm/powerpc.rs @@ -1,5 +1,4 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; -use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; diff --git a/compiler/rustc_target/src/asm/riscv.rs b/compiler/rustc_target/src/asm/riscv.rs index 2505d36f5b8a..3845a0e14af0 100644 --- a/compiler/rustc_target/src/asm/riscv.rs +++ b/compiler/rustc_target/src/asm/riscv.rs @@ -1,7 +1,6 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; use crate::spec::{RelocModel, Target}; use rustc_data_structures::fx::FxIndexSet; -use rustc_macros::HashStable_Generic; use rustc_span::{sym, Symbol}; use std::fmt; diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs index 6bc668454b19..2bab41cd8a1b 100644 --- a/compiler/rustc_target/src/asm/s390x.rs +++ b/compiler/rustc_target/src/asm/s390x.rs @@ -1,5 +1,4 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; -use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; diff --git a/compiler/rustc_target/src/asm/spirv.rs b/compiler/rustc_target/src/asm/spirv.rs index d13a6131f9ab..f242faec0266 100644 --- a/compiler/rustc_target/src/asm/spirv.rs +++ b/compiler/rustc_target/src/asm/spirv.rs @@ -1,5 +1,4 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; -use rustc_macros::HashStable_Generic; use rustc_span::Symbol; def_reg_class! { diff --git a/compiler/rustc_target/src/asm/wasm.rs b/compiler/rustc_target/src/asm/wasm.rs index eb0b23ef43dd..b5f4d10fb2b4 100644 --- a/compiler/rustc_target/src/asm/wasm.rs +++ b/compiler/rustc_target/src/asm/wasm.rs @@ -1,5 +1,4 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; -use rustc_macros::HashStable_Generic; use rustc_span::Symbol; def_reg_class! { diff --git a/compiler/rustc_target/src/asm/x86.rs b/compiler/rustc_target/src/asm/x86.rs index 3b5da8806ccc..28413a5bcbd1 100644 --- a/compiler/rustc_target/src/asm/x86.rs +++ b/compiler/rustc_target/src/asm/x86.rs @@ -1,7 +1,6 @@ use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; use crate::spec::{RelocModel, Target}; use rustc_data_structures::fx::FxIndexSet; -use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index ba359ac6de13..e096fb4fd10f 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -20,9 +20,6 @@ use std::path::{Path, PathBuf}; -#[macro_use] -extern crate rustc_macros; - #[macro_use] extern crate tracing; diff --git a/compiler/rustc_target/src/spec/abi/mod.rs b/compiler/rustc_target/src/spec/abi/mod.rs index 388e76d83e24..bf51bb4bf825 100644 --- a/compiler/rustc_target/src/spec/abi/mod.rs +++ b/compiler/rustc_target/src/spec/abi/mod.rs @@ -1,6 +1,6 @@ use std::fmt; -use rustc_macros::HashStable_Generic; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::symbol::sym; use rustc_span::{Span, Symbol}; diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 291a761913bf..c6e304a408b9 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -40,6 +40,7 @@ use crate::json::{Json, ToJson}; use crate::spec::abi::Abi; use crate::spec::crt_objects::CrtObjects; use rustc_fs_util::try_canonicalize; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_span::symbol::{kw, sym, Symbol}; use serde_json::Value; @@ -51,8 +52,6 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; use std::{fmt, io}; -use rustc_macros::HashStable_Generic; - pub mod abi; pub mod crt_objects; diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 9b08a86ef160..7228a9ba0167 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -3,7 +3,7 @@ use rustc_errors::{ codes::*, Applicability, Diag, DiagCtxt, Diagnostic, EmissionGuarantee, Level, SubdiagMessageOp, Subdiagnostic, }; -use rustc_macros::Diagnostic; +use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_middle::ty::{self, ClosureKind, PolyTraitRef, Ty}; use rustc_span::{Span, Symbol}; diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 0595e82b39ed..b2400cec42f1 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -1,10 +1,9 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -use crate::traits::{self, ObligationCtxt, SelectionContext}; - -use crate::traits::TraitEngineExt as _; +use crate::traits::{self, ObligationCtxt, SelectionContext, TraitEngineExt as _}; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_infer::traits::{Obligation, TraitEngine, TraitEngineExt as _}; +use rustc_macros::extension; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::infer::canonical::{Canonical, CanonicalQueryResponse, QueryResponse}; use rustc_middle::traits::query::NoSolution; diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index d54f714b22c6..4b2d2af21e01 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -29,8 +29,6 @@ #![feature(type_alias_impl_trait)] #![recursion_limit = "512"] // For rustdoc -#[macro_use] -extern crate rustc_macros; #[cfg(target_pointer_width = "64")] #[macro_use] extern crate rustc_data_structures; diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs index 222d0b4d5e75..5e0d7da4f06b 100644 --- a/compiler/rustc_trait_selection/src/regions.rs +++ b/compiler/rustc_trait_selection/src/regions.rs @@ -1,5 +1,6 @@ use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{InferCtxt, RegionResolutionError}; +use rustc_macros::extension; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::ObligationCause; diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index a778414d9d1b..a8b1a182d3c2 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -4,6 +4,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::LangItem; use rustc_hir::{def_id::DefId, Movability, Mutability}; use rustc_infer::traits::query::NoSolution; +use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::traits::solve::Goal; use rustc_middle::ty::{ self, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 21efce748792..8553ef0898d7 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -9,6 +9,7 @@ use rustc_infer::infer::{ use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::{MaybeCause, NestedNormalizationGoals}; use rustc_infer::traits::ObligationCause; +use rustc_macros::{extension, HashStable}; use rustc_middle::infer::canonical::CanonicalVarInfos; use rustc_middle::infer::unify_key::ConstVariableOrigin; use rustc_middle::traits::solve::inspect; diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs index 6644d3c77afd..c692b00b6d74 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs @@ -4,6 +4,7 @@ use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt}; use rustc_infer::traits::{ Obligation, PolyTraitObligation, PredicateObligation, Selection, SelectionResult, TraitEngine, }; +use rustc_macros::extension; use rustc_middle::traits::solve::{CandidateSource, CanonicalInput, Certainty, Goal}; use rustc_middle::traits::{ BuiltinImplSource, ImplSource, ImplSourceUserDefinedData, ObligationCause, SelectionError, diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index e918f20577cc..9c366c1dda3a 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -14,6 +14,7 @@ use rustc_ast_ir::visit::VisitorResult; use rustc_infer::infer::resolve::EagerResolver; use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; +use rustc_macros::extension; use rustc_middle::infer::unify_key::ConstVariableOrigin; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{inspect, QueryResult}; diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index e58babe32089..b2b076e28e64 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -16,6 +16,7 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_infer::traits::query::NoSolution; +use rustc_macros::extension; use rustc_middle::infer::canonical::CanonicalVarInfos; use rustc_middle::traits::solve::{ CanonicalResponse, Certainty, ExternalConstraintsData, Goal, GoalSource, QueryResult, Response, diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 9fbec174ce8d..432d51ff8f90 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -19,6 +19,7 @@ use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; use rustc_infer::traits::{ FulfillmentError, Obligation, ObligationCause, PredicateObligation, TraitEngineExt as _, }; +use rustc_macros::extension; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::error::TypeError; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs index d41d43bad718..9e5701ffffc6 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs @@ -4,6 +4,7 @@ use crate::traits::{Obligation, ObligationCause, ObligationCtxt}; use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, Diag}; use rustc_hir as hir; use rustc_hir::Node; +use rustc_macros::extension; use rustc_middle::ty::{self, Ty}; use rustc_span::{Span, DUMMY_SP}; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index b418219fb957..07bd209e6239 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -9,6 +9,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_macros::{extension, LintDiagnostic}; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt}; use rustc_parse_format::{ParseMode, Parser, Piece, Position}; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index d24942f3f46c..3d2574ac92b6 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -26,6 +26,7 @@ use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, HirId use rustc_infer::infer::error_reporting::TypeErrCtxt; use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk}; +use rustc_macros::extension; use rustc_middle::hir::map; use rustc_middle::traits::IsConstable; use rustc_middle::ty::error::TypeError::{self, Sorts}; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 1971136e54c7..7e30fb608972 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -32,6 +32,7 @@ use rustc_hir::intravisit::Visitor; use rustc_hir::{GenericParam, Item, Node}; use rustc_infer::infer::error_reporting::TypeErrCtxt; use rustc_infer::infer::{InferOk, TypeTrace}; +use rustc_macros::extension; use rustc_middle::traits::select::OverflowError; use rustc_middle::traits::SignatureMismatchData; use rustc_middle::ty::abstract_const::NotConstEvaluatable; diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index b4969926f642..43f4fa8e81ca 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -8,6 +8,7 @@ use rustc_infer::infer::at::At; use rustc_infer::infer::InferOk; use rustc_infer::traits::PredicateObligation; use rustc_infer::traits::{FulfillmentError, Normalized, Obligation, TraitEngine}; +use rustc_macros::extension; use rustc_middle::traits::{ObligationCause, ObligationCauseCode, Reveal}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFolder}; use rustc_middle::ty::{TypeFoldable, TypeSuperFoldable, TypeVisitable, TypeVisitableExt}; diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index c4110df45dbb..1dd2ada3356f 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -3,6 +3,7 @@ use crate::traits::{ObligationCause, ObligationCtxt}; use rustc_data_structures::fx::FxIndexSet; use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::infer::InferOk; +use rustc_macros::extension; use rustc_middle::infer::canonical::{OriginalQueryValues, QueryRegionConstraints}; use rustc_middle::ty::{self, ParamEnv, Ty, TypeFolder, TypeVisitableExt}; use rustc_span::def_id::LocalDefId; diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs index 16ee9fadab4f..5f2a89441352 100644 --- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs +++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs @@ -1,4 +1,5 @@ use rustc_infer::traits::{TraitEngine, TraitEngineExt}; +use rustc_macros::extension; use crate::infer::canonical::OriginalQueryValues; use crate::infer::InferCtxt; diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index c520e699bf54..8b39c23da56b 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -13,6 +13,7 @@ use crate::traits::{ObligationCause, PredicateObligation, Reveal}; use rustc_data_structures::sso::SsoHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::traits::Normalized; +use rustc_macros::extension; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor}; diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index 423ed0f7105b..f7e84a46639d 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -7,6 +7,7 @@ use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::outlives::components::{push_outlives_components, Component}; use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::traits::query::OutlivesBound; +use rustc_macros::{HashStable, TypeFoldable, TypeVisitable}; use rustc_middle::infer::canonical::CanonicalQueryResponse; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFolder, TypeVisitableExt}; diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs index 07587e374118..3e7aa52dcfea 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs @@ -3,6 +3,7 @@ use crate::traits::query::dropck_outlives::{ compute_dropck_outlives_inner, trivial_dropck_outlives, }; use crate::traits::ObligationCtxt; +use rustc_macros::{HashStable, TypeFoldable, TypeVisitable}; use rustc_middle::traits::query::{DropckOutlivesResult, NoSolution}; use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt}; diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs index dba014d58b00..681f84f20428 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs @@ -3,6 +3,7 @@ use super::OverlapError; use crate::traits; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; +use rustc_macros::extension; use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams}; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs index 5746e20490d0..64ab8378abb0 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs @@ -1,6 +1,7 @@ use rustc_infer::infer::at::At; use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::traits::{FulfillmentError, TraitEngine}; +use rustc_macros::extension; use rustc_middle::ty::{self, Ty}; use crate::traits::{NormalizeExt, Obligation}; diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index 06a5051956a4..f041c5831fc7 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -1,5 +1,7 @@ use rustc_ast_ir::try_visit; use rustc_ast_ir::visit::VisitorResult; +#[cfg(feature = "nightly")] +use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; use std::fmt; use std::hash::Hash; diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 5b08140db3a3..c1506f9252b0 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -1,5 +1,7 @@ #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +#[cfg(feature = "nightly")] +use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; use std::fmt; use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, WithInfcx}; diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index a5b33a8125d5..5aa4895633c2 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -10,12 +10,11 @@ extern crate self as rustc_type_ir; #[macro_use] extern crate bitflags; -#[cfg(feature = "nightly")] -#[macro_use] -extern crate rustc_macros; #[cfg(feature = "nightly")] use rustc_data_structures::sync::Lrc; +#[cfg(feature = "nightly")] +use rustc_macros::{Decodable, Encodable, HashStable_NoContext}; use std::fmt; use std::hash::Hash; #[cfg(not(feature = "nightly"))] diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs index 112f617fe166..5260d9061cfc 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs @@ -1,5 +1,7 @@ use rustc_ast_ir::try_visit; use rustc_ast_ir::visit::VisitorResult; +#[cfg(feature = "nightly")] +use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable}; use std::fmt; use crate::fold::{FallibleTypeFolder, TypeFoldable}; diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs index e1247e2661a2..d1b86b495e9d 100644 --- a/compiler/rustc_type_ir/src/region_kind.rs +++ b/compiler/rustc_type_ir/src/region_kind.rs @@ -1,5 +1,7 @@ #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +#[cfg(feature = "nightly")] +use rustc_macros::{TyDecodable, TyEncodable}; use std::fmt; use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, WithInfcx}; diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 3924b371bbce..f2e4afecc402 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -3,6 +3,8 @@ use rustc_ast_ir::try_visit; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; #[cfg(feature = "nightly")] use rustc_data_structures::unify::{EqUnifyValue, UnifyKey}; +#[cfg(feature = "nightly")] +use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable}; use std::fmt; use crate::fold::{FallibleTypeFolder, TypeFoldable}; From 5969ad4caef5b6f28312fc00aab16306ad4d88f7 Mon Sep 17 00:00:00 2001 From: Nicholas Thompson Date: Sun, 28 Apr 2024 21:00:53 -0400 Subject: [PATCH 140/279] Update is_val_statically_known docs * Add `Type Requirements` section, listing the allowed inputs, as requested by #121115 * Add `Pointers` subsection, explaining is_val_statically_known handles pointers. * Add `Stability concerns` section, referring to other documentation relating to consistency in `const` functions. --- library/core/src/intrinsics.rs | 43 ++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 4b00bbe4dc2e..14b4ce39ab45 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2717,10 +2717,45 @@ where /// particular value, ever. However, the compiler will generally make it /// return `true` only if the value of the argument is actually known. /// -/// When calling this in a `const fn`, both paths must be semantically -/// equivalent, that is, the result of the `true` branch and the `false` -/// branch must return the same value and have the same side-effects *no -/// matter what*. +/// # Stability concerns +/// +/// While it is safe to call, this intrinsic may behave differently in +/// a `const` context than otherwise. See the [`const_eval_select`] +/// documentation for an explanation of the issues this can cause. Unlike +/// `const_eval_select`, this intrinsic isn't guaranteed to behave +/// deterministically even in a `const` context. +/// +/// # Type Requirements +/// +/// `T` must be either a `bool`, a `char`, a primitive numeric type (e.g. `f32`, +/// but not `NonZeroISize`), or any thin pointer (e.g. `*mut String`). +/// Any other argument types *may* cause a compiler error. +/// +/// ## Pointers +/// +/// When the input is a pointer, only the pointer itself is +/// ever considered. The pointee has no effect. Currently, these functions +/// behave identically: +/// +/// ``` +/// #![feature(is_val_statically_known)] +/// #![feature(core_intrinsics)] +/// # #![allow(internal_features)] +/// #![feature(strict_provenance)] +/// use std::intrinsics::is_val_statically_known; +/// +/// fn foo(x: &i32) -> bool { +/// is_val_statically_known(x) +/// } +/// +/// fn bar(x: &i32) -> bool { +/// is_val_statically_known( +/// (x as *const i32).addr() +/// ) +/// } +/// # _ = foo(&5_i32); +/// # _ = bar(&5_i32); +/// ``` #[rustc_const_unstable(feature = "is_val_statically_known", issue = "none")] #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] From 6ce258f6572425d10f3ae6e76340d3f2a45dac12 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 29 Apr 2024 11:14:55 +1000 Subject: [PATCH 141/279] Remove `extern crate rustc_macros` from `rustc_middle`. --- compiler/rustc_middle/src/error.rs | 2 +- compiler/rustc_middle/src/hir/mod.rs | 1 + compiler/rustc_middle/src/hir/place.rs | 1 + compiler/rustc_middle/src/infer/canonical.rs | 2 +- compiler/rustc_middle/src/infer/mod.rs | 1 + compiler/rustc_middle/src/lib.rs | 2 -- compiler/rustc_middle/src/lint.rs | 1 + compiler/rustc_middle/src/metadata.rs | 2 +- compiler/rustc_middle/src/middle/codegen_fn_attrs.rs | 1 + compiler/rustc_middle/src/middle/debugger_visualizer.rs | 1 + compiler/rustc_middle/src/middle/dependency_format.rs | 1 + compiler/rustc_middle/src/middle/exported_symbols.rs | 2 +- compiler/rustc_middle/src/middle/mod.rs | 1 + compiler/rustc_middle/src/middle/region.rs | 2 +- compiler/rustc_middle/src/middle/resolve_bound_vars.rs | 2 +- compiler/rustc_middle/src/middle/stability.rs | 1 + compiler/rustc_middle/src/mir/basic_blocks.rs | 1 + compiler/rustc_middle/src/mir/consts.rs | 1 + compiler/rustc_middle/src/mir/coverage.rs | 2 +- compiler/rustc_middle/src/mir/interpret/allocation.rs | 1 + .../rustc_middle/src/mir/interpret/allocation/init_mask.rs | 1 + .../src/mir/interpret/allocation/provenance_map.rs | 1 + compiler/rustc_middle/src/mir/interpret/error.rs | 2 +- compiler/rustc_middle/src/mir/interpret/mod.rs | 2 +- compiler/rustc_middle/src/mir/interpret/pointer.rs | 2 +- compiler/rustc_middle/src/mir/interpret/value.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 1 + compiler/rustc_middle/src/mir/mono.rs | 1 + compiler/rustc_middle/src/mir/query.rs | 1 + compiler/rustc_middle/src/mir/syntax.rs | 1 + compiler/rustc_middle/src/mir/terminator.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 1 + compiler/rustc_middle/src/query/on_disk_cache.rs | 1 + compiler/rustc_middle/src/query/plumbing.rs | 1 + compiler/rustc_middle/src/thir.rs | 1 + compiler/rustc_middle/src/traits/mod.rs | 3 +++ compiler/rustc_middle/src/traits/query.rs | 2 ++ compiler/rustc_middle/src/traits/select.rs | 1 + compiler/rustc_middle/src/traits/solve.rs | 1 + compiler/rustc_middle/src/traits/solve/inspect.rs | 1 + compiler/rustc_middle/src/traits/specialization_graph.rs | 1 + compiler/rustc_middle/src/ty/abstract_const.rs | 1 + compiler/rustc_middle/src/ty/adjustment.rs | 2 +- compiler/rustc_middle/src/ty/adt.rs | 4 ++-- compiler/rustc_middle/src/ty/assoc.rs | 1 + compiler/rustc_middle/src/ty/cast.rs | 2 +- compiler/rustc_middle/src/ty/closure.rs | 1 + compiler/rustc_middle/src/ty/consts.rs | 2 +- compiler/rustc_middle/src/ty/consts/kind.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_middle/src/ty/error.rs | 1 + compiler/rustc_middle/src/ty/fast_reject.rs | 1 + compiler/rustc_middle/src/ty/generic_args.rs | 4 +++- compiler/rustc_middle/src/ty/generics.rs | 1 + .../rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs | 1 + compiler/rustc_middle/src/ty/instance.rs | 4 +++- compiler/rustc_middle/src/ty/intrinsic.rs | 1 + compiler/rustc_middle/src/ty/layout.rs | 1 + compiler/rustc_middle/src/ty/mod.rs | 4 +++- compiler/rustc_middle/src/ty/normalize_erasing_regions.rs | 1 + compiler/rustc_middle/src/ty/pattern.rs | 1 + compiler/rustc_middle/src/ty/predicate.rs | 1 + compiler/rustc_middle/src/ty/print/pretty.rs | 1 + compiler/rustc_middle/src/ty/region.rs | 1 + compiler/rustc_middle/src/ty/relate.rs | 1 + compiler/rustc_middle/src/ty/rvalue_scopes.rs | 1 + compiler/rustc_middle/src/ty/sty.rs | 2 +- compiler/rustc_middle/src/ty/trait_def.rs | 2 +- compiler/rustc_middle/src/ty/typeck_results.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 2 +- compiler/rustc_middle/src/ty/vtable.rs | 1 + 71 files changed, 80 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index 0d3cffd20477..6e622b0405f0 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -1,7 +1,7 @@ use std::fmt; use rustc_errors::{codes::*, DiagArgName, DiagArgValue, DiagMessage}; -use rustc_macros::Diagnostic; +use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; use crate::ty::Ty; diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 94d1039c763f..34748afa863d 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -15,6 +15,7 @@ use rustc_data_structures::sync::{try_par_for_each_in, DynSend, DynSync}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::*; +use rustc_macros::{Decodable, Encodable, HashStable}; use rustc_span::{ErrorGuaranteed, ExpnId}; /// Gather the LocalDefId for each item-like within a module, including items contained within diff --git a/compiler/rustc_middle/src/hir/place.rs b/compiler/rustc_middle/src/hir/place.rs index 32f3a177508f..1ac35314ead2 100644 --- a/compiler/rustc_middle/src/hir/place.rs +++ b/compiler/rustc_middle/src/hir/place.rs @@ -2,6 +2,7 @@ use crate::ty; use crate::ty::Ty; use rustc_hir::HirId; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_target::abi::{FieldIdx, VariantIdx}; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 62d7b7c28d1f..aee97d772229 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -23,7 +23,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lock; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_type_ir::Canonical as IrCanonical; use rustc_type_ir::CanonicalVarInfo as IrCanonicalVarInfo; pub use rustc_type_ir::{CanonicalTyVarKind, CanonicalVarKind}; diff --git a/compiler/rustc_middle/src/infer/mod.rs b/compiler/rustc_middle/src/infer/mod.rs index 1384611e1467..f74f71b6b378 100644 --- a/compiler/rustc_middle/src/infer/mod.rs +++ b/compiler/rustc_middle/src/infer/mod.rs @@ -4,6 +4,7 @@ pub mod unify_key; use crate::ty::Region; use crate::ty::{OpaqueTypeKey, Ty}; use rustc_data_structures::sync::Lrc; +use rustc_macros::{HashStable, TypeFoldable, TypeVisitable}; use rustc_span::Span; /// Requires that `region` must be equal to one of the regions in `choice_regions`. diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 501052b7411b..9afc68ef2306 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -68,8 +68,6 @@ #[macro_use] extern crate bitflags; #[macro_use] -extern crate rustc_macros; -#[macro_use] extern crate rustc_data_structures; #[macro_use] extern crate tracing; diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 8d9e0dfd8690..086582e60a3c 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -4,6 +4,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sorted_map::SortedMap; use rustc_errors::{Diag, DiagMessage, MultiSpan}; use rustc_hir::{HirId, ItemLocalId}; +use rustc_macros::HashStable; use rustc_session::lint::{ builtin::{self, FORBIDDEN_LINT_GROUPS}, FutureIncompatibilityReason, Level, Lint, LintId, diff --git a/compiler/rustc_middle/src/metadata.rs b/compiler/rustc_middle/src/metadata.rs index 674402cb4bf9..589f274eb176 100644 --- a/compiler/rustc_middle/src/metadata.rs +++ b/compiler/rustc_middle/src/metadata.rs @@ -1,7 +1,7 @@ use crate::ty; use rustc_hir::def::Res; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_span::def_id::DefId; use rustc_span::symbol::Ident; use smallvec::SmallVec; diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index ec9697bbd355..8fabd80658ac 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -1,5 +1,6 @@ use crate::mir::mono::Linkage; use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr}; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_span::symbol::Symbol; use rustc_target::abi::Align; use rustc_target::spec::SanitizerSet; diff --git a/compiler/rustc_middle/src/middle/debugger_visualizer.rs b/compiler/rustc_middle/src/middle/debugger_visualizer.rs index a0497d805dad..74a5dfb04009 100644 --- a/compiler/rustc_middle/src/middle/debugger_visualizer.rs +++ b/compiler/rustc_middle/src/middle/debugger_visualizer.rs @@ -1,4 +1,5 @@ use rustc_data_structures::sync::Lrc; +use rustc_macros::{Decodable, Encodable, HashStable}; use std::path::PathBuf; #[derive(HashStable)] diff --git a/compiler/rustc_middle/src/middle/dependency_format.rs b/compiler/rustc_middle/src/middle/dependency_format.rs index e079843bfbc3..e7d0cffc85cf 100644 --- a/compiler/rustc_middle/src/middle/dependency_format.rs +++ b/compiler/rustc_middle/src/middle/dependency_format.rs @@ -4,6 +4,7 @@ //! For all the gory details, see the provider of the `dependency_formats` //! query. +use rustc_macros::{Decodable, Encodable, HashStable}; use rustc_session::config::CrateType; /// A list of dependencies for a certain crate type. diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs index 123b32f4aea9..3b6eecb7fa04 100644 --- a/compiler/rustc_middle/src/middle/exported_symbols.rs +++ b/compiler/rustc_middle/src/middle/exported_symbols.rs @@ -1,7 +1,7 @@ use crate::ty::GenericArgsRef; use crate::ty::{self, Ty, TyCtxt}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; -use rustc_macros::HashStable; +use rustc_macros::{Decodable, Encodable, HashStable, TyDecodable, TyEncodable}; /// The SymbolExportLevel of a symbols specifies from which kinds of crates /// the symbol will be exported. `C` symbols will be exported from any diff --git a/compiler/rustc_middle/src/middle/mod.rs b/compiler/rustc_middle/src/middle/mod.rs index bdb2270611a9..5c395afadd7f 100644 --- a/compiler/rustc_middle/src/middle/mod.rs +++ b/compiler/rustc_middle/src/middle/mod.rs @@ -5,6 +5,7 @@ pub mod exported_symbols; pub mod lang_items; pub mod lib_features { use rustc_data_structures::unord::UnordMap; + use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_span::{symbol::Symbol, Span}; #[derive(Copy, Clone, Debug, PartialEq, Eq)] diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index 5ae60e042771..da32dbc3065a 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -11,7 +11,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::UnordMap; use rustc_hir as hir; use rustc_hir::{HirId, HirIdMap, Node}; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_span::{Span, DUMMY_SP}; use std::fmt; diff --git a/compiler/rustc_middle/src/middle/resolve_bound_vars.rs b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs index 610afd95f3c6..d0103f622313 100644 --- a/compiler/rustc_middle/src/middle/resolve_bound_vars.rs +++ b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs @@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; use rustc_hir::{ItemLocalId, OwnerId}; -use rustc_macros::HashStable; +use rustc_macros::{Decodable, Encodable, HashStable, TyDecodable, TyEncodable}; #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)] pub enum ResolvedArg { diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index c393287da95c..67bd53f53dae 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -14,6 +14,7 @@ use rustc_feature::GateIssue; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap}; use rustc_hir::{self as hir, HirId}; +use rustc_macros::{Decodable, Encodable, HashStable}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE}; use rustc_session::lint::{BuiltinLintDiag, Level, Lint, LintBuffer}; diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index 1086d647721b..f9398b254c7b 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -7,6 +7,7 @@ use rustc_data_structures::graph::dominators::{dominators, Dominators}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::OnceLock; use rustc_index::{IndexSlice, IndexVec}; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use smallvec::SmallVec; diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index 6ff40c53c853..dfb645e6a228 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -1,6 +1,7 @@ use std::fmt::{self, Debug, Display, Formatter}; use rustc_hir::def_id::DefId; +use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_session::{config::RemapPathScopeComponents, RemapFileNameExt}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{HasDataLayout, Size}; diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index 04011fd41948..c7fdf54d305d 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -1,7 +1,7 @@ //! Metadata from source code coverage analysis and instrumentation. use rustc_index::IndexVec; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_span::{Span, Symbol}; use std::fmt::{self, Debug, Formatter}; diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 00faa2118537..9cc5c6a2ee94 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -14,6 +14,7 @@ use either::{Left, Right}; use rustc_ast::Mutability; use rustc_data_structures::intern::Interned; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_target::abi::{Align, HasDataLayout, Size}; use super::{ diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs index 2c6bb908f39f..d60db775ff08 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs @@ -5,6 +5,7 @@ use std::hash; use std::iter; use std::ops::Range; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_serialize::{Decodable, Encodable}; use rustc_target::abi::Size; use rustc_type_ir::{TyDecoder, TyEncoder}; diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs index 9459af490e32..e974279f1917 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs @@ -4,6 +4,7 @@ use std::cmp; use rustc_data_structures::sorted_map::SortedMap; +use rustc_macros::HashStable; use rustc_target::abi::{HasDataLayout, Size}; use super::{alloc_range, AllocError, AllocRange, AllocResult, CtfeProvenance, Provenance}; diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index a3d16d4f097a..93044a1c53ed 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -7,7 +7,7 @@ use crate::ty::{self, layout, tls, Ty, TyCtxt, ValTree}; use rustc_ast_ir::Mutability; use rustc_data_structures::sync::Lock; use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage, ErrorGuaranteed, IntoDiagArg}; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_session::CtfeBacktrace; use rustc_span::{def_id::DefId, Span, DUMMY_SP}; use rustc_target::abi::{call, Align, Size, VariantIdx, WrappingRange}; diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 6275942bafe6..ee3cdf36820d 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -131,7 +131,7 @@ use rustc_data_structures::sync::{HashMapExt, Lock}; use rustc_data_structures::tiny_list::TinyList; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_serialize::{Decodable, Encodable}; use rustc_target::abi::{AddressSpace, Endian, HasDataLayout}; diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs index e2767ee29895..ff57053fa051 100644 --- a/compiler/rustc_middle/src/mir/interpret/pointer.rs +++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs @@ -1,6 +1,6 @@ use super::{AllocId, InterpResult}; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_target::abi::{HasDataLayout, Size}; use std::{fmt, num::NonZero}; diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index 9728967860a0..352409bcef98 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -6,7 +6,7 @@ use rustc_apfloat::{ ieee::{Double, Half, Quad, Single}, Float, }; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_target::abi::{HasDataLayout, Size}; use crate::ty::ScalarInt; diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 8555aa48c306..25cc9ac47c83 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -20,6 +20,7 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; use rustc_hir::{ self as hir, BindingMode, ByRef, CoroutineDesugaring, CoroutineKind, HirId, ImplicitSelfKind, }; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_session::Session; use rustc_span::source_map::Spanned; use rustc_target::abi::{FieldIdx, VariantIdx}; diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 9eed70197823..6d4585cfbc66 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -9,6 +9,7 @@ use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher}; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_hir::ItemId; use rustc_index::Idx; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_query_system::ich::StableHashingContext; use rustc_session::config::OptLevel; use rustc_span::symbol::Symbol; diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index e3f58729fbd1..9a7af6135e46 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -7,6 +7,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::BitMatrix; use rustc_index::{Idx, IndexVec}; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_span::symbol::Symbol; use rustc_span::Span; use rustc_target::abi::{FieldIdx, VariantIdx}; diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 5ddd71178ca3..bfa243612e96 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -17,6 +17,7 @@ use rustc_data_structures::packed::Pu128; use rustc_hir::def_id::DefId; use rustc_hir::CoroutineKind; use rustc_index::IndexVec; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_span::source_map::Spanned; use rustc_target::abi::{FieldIdx, VariantIdx}; diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index 58a27c1f9ef5..5acf37325bce 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -4,7 +4,7 @@ use smallvec::SmallVec; use super::TerminatorKind; use rustc_data_structures::packed::Pu128; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use std::slice; use super::*; diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index a5d21c47e5b2..f689a73d4bc2 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -72,6 +72,7 @@ use rustc_hir::def_id::{ use rustc_hir::lang_items::{LangItem, LanguageItems}; use rustc_hir::{Crate, ItemLocalId, ItemLocalMap, TraitCandidate}; use rustc_index::IndexVec; +use rustc_macros::rustc_queries; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{try_get_cached, QueryCache, QueryMode, QueryState}; use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index db1b5a74f0ae..2dcb58729ff9 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs @@ -6,6 +6,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, StableCrateId, LOCAL_CRATE}; use rustc_hir::definitions::DefPathHash; use rustc_index::{Idx, IndexVec}; +use rustc_macros::{Decodable, Encodable}; use rustc_middle::dep_graph::{DepNodeIndex, SerializedDepNodeIndex}; use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use rustc_middle::mir::{self, interpret}; diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 038d3fe93c4b..8a4e3ab0e619 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -12,6 +12,7 @@ use rustc_data_structures::sync::AtomicU64; use rustc_data_structures::sync::WorkerLocal; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::hir_id::OwnerId; +use rustc_macros::HashStable; use rustc_query_system::dep_graph::DepNodeIndex; use rustc_query_system::dep_graph::SerializedDepNodeIndex; pub(crate) use rustc_query_system::query::QueryJobId; diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 99498fedcca9..3940d18bc591 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -15,6 +15,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd}; use rustc_index::newtype_index; use rustc_index::IndexVec; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeVisitable}; use rustc_middle::middle::region; use rustc_middle::mir::interpret::AllocId; use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp}; diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index b1e34dcd5f3f..3804dd6c4df8 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -20,6 +20,9 @@ use rustc_errors::{Applicability, Diag, EmissionGuarantee}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::HirId; +use rustc_macros::{ + Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, +}; use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 12e4f70ba575..70f3532e3ab1 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -10,11 +10,13 @@ use crate::infer::canonical::{Canonical, QueryResponse}; use crate::ty::error::TypeError; use crate::ty::GenericArg; use crate::ty::{self, Ty, TyCtxt}; +use rustc_macros::{HashStable, TypeFoldable, TypeVisitable}; use rustc_span::Span; pub mod type_op { use crate::ty::fold::TypeFoldable; use crate::ty::{Predicate, Ty, TyCtxt, UserType}; + use rustc_macros::{HashStable, TypeFoldable, TypeVisitable}; use std::fmt; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, TypeVisitable)] diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index c35524373c7a..c8caf228ffb5 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -10,6 +10,7 @@ use rustc_errors::ErrorGuaranteed; use crate::ty; use rustc_hir::def_id::DefId; +use rustc_macros::{HashStable, TypeVisitable}; use rustc_query_system::cache::Cache; pub type SelectionCache<'tcx> = Cache< diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs index 13504c6ae930..13f26ab2b2b5 100644 --- a/compiler/rustc_middle/src/traits/solve.rs +++ b/compiler/rustc_middle/src/traits/solve.rs @@ -1,5 +1,6 @@ use rustc_ast_ir::try_visit; use rustc_data_structures::intern::Interned; +use rustc_macros::{HashStable, TypeFoldable, TypeVisitable}; use rustc_span::def_id::DefId; use crate::infer::canonical::{CanonicalVarValues, QueryRegionConstraints}; diff --git a/compiler/rustc_middle/src/traits/solve/inspect.rs b/compiler/rustc_middle/src/traits/solve/inspect.rs index 1b2e2781bfe7..64e842375400 100644 --- a/compiler/rustc_middle/src/traits/solve/inspect.rs +++ b/compiler/rustc_middle/src/traits/solve/inspect.rs @@ -24,6 +24,7 @@ use super::{ }; use crate::{infer::canonical::CanonicalVarValues, ty}; use format::ProofTreeFormatter; +use rustc_macros::{TypeFoldable, TypeVisitable}; use std::fmt::{Debug, Write}; mod format; diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index ba29d4040a1e..ff5d51bcb66f 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -5,6 +5,7 @@ use crate::ty::{self, TyCtxt}; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::{DefId, DefIdMap}; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_span::symbol::sym; /// A per-trait graph of impls in specialization order. At the moment, this diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index 570f896ba299..dc46b470b6f4 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -4,6 +4,7 @@ use crate::ty::{ TypeVisitableExt, }; use rustc_errors::ErrorGuaranteed; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeVisitable}; #[derive(Hash, Debug, Clone, Copy, Ord, PartialOrd, PartialEq, Eq)] #[derive(TyDecodable, TyEncodable, HashStable, TypeVisitable, TypeFoldable)] diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index c3e8991c63a2..9badf65115ed 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -1,7 +1,7 @@ use crate::ty::{self, Ty, TyCtxt}; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_span::Span; use rustc_target::abi::FieldIdx; diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index a7f1ba46b617..87b6a6079520 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -12,6 +12,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_index::{IndexSlice, IndexVec}; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_query_system::ich::StableHashingContext; use rustc_session::DataTypeKind; use rustc_span::symbol::sym; @@ -582,8 +583,7 @@ impl<'tcx> AdtDef<'tcx> { } } -#[derive(Clone, Copy, Debug)] -#[derive(HashStable)] +#[derive(Clone, Copy, Debug, HashStable)] pub enum Representability { Representable, Infinite(ErrorGuaranteed), diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index 94a5ff13158a..1cdde3f057c6 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -3,6 +3,7 @@ use rustc_data_structures::sorted_map::SortedIndexMultiMap; use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def_id::DefId; +use rustc_macros::{Decodable, Encodable, HashStable}; use rustc_span::symbol::{Ident, Symbol}; use super::{TyCtxt, Visibility}; diff --git a/compiler/rustc_middle/src/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs index c9fd20bc1126..26c5a865fdc2 100644 --- a/compiler/rustc_middle/src/ty/cast.rs +++ b/compiler/rustc_middle/src/ty/cast.rs @@ -4,7 +4,7 @@ use crate::ty::{self, Ty}; use rustc_middle::mir; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; /// Types that are represented as ints. #[derive(Copy, Clone, Debug, PartialEq, Eq)] diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index b66c664e6ae1..8096acd9b0fe 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -11,6 +11,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::HirId; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_span::def_id::LocalDefIdMap; use rustc_span::symbol::Ident; use rustc_span::{Span, Symbol}; diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index fd4573c16031..7fe63cbe8240 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -6,7 +6,7 @@ use rustc_error_messages::MultiSpan; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::LocalDefId; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_type_ir::ConstKind as IrConstKind; use rustc_type_ir::{ConstTy, IntoKind, TypeFlags, WithCachedTypeInfo}; diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index a7e0a0402ce9..60b242c9f666 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -4,7 +4,7 @@ use crate::ty::abstract_const::CastKind; use crate::ty::GenericArgsRef; use crate::ty::{self, visit::TypeVisitableExt as _, List, Ty, TyCtxt}; use rustc_hir::def_id::DefId; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; /// An unevaluated (potentially generic) constant used in the type-system. #[derive(Copy, Clone, Eq, PartialEq, TyEncodable, TyDecodable)] diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 45fa5e8f7ca3..434c95370744 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -56,7 +56,7 @@ use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir::{HirId, Node, TraitCandidate}; use rustc_index::IndexVec; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_query_system::dep_graph::DepNodeIndex; use rustc_query_system::ich::StableHashingContext; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index ce85c28ece89..71437ce1df9d 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -4,6 +4,7 @@ use rustc_errors::pluralize; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind}; use rustc_hir::def_id::DefId; +use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_span::symbol::Symbol; use rustc_target::spec::abi; use std::borrow::Cow; diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 10b0909209a0..15f048ab598c 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -2,6 +2,7 @@ use crate::mir::Mutability; use crate::ty::GenericArgKind; use crate::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt}; use rustc_hir::def_id::DefId; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use std::fmt::Debug; use std::hash::Hash; use std::iter; diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index 19cef927faf5..de2c01c30461 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -11,7 +11,9 @@ use rustc_ast_ir::walk_visitable_list; use rustc_data_structures::intern::Interned; use rustc_errors::{DiagArgValue, IntoDiagArg}; use rustc_hir::def_id::DefId; -use rustc_macros::HashStable; +use rustc_macros::{ + Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, +}; use rustc_serialize::{Decodable, Encodable}; use rustc_type_ir::WithCachedTypeInfo; use smallvec::SmallVec; diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index a99196cb3630..6bf2051d67cc 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -3,6 +3,7 @@ use crate::ty::{EarlyBinder, GenericArgsRef}; use rustc_ast as ast; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_span::symbol::{kw, Symbol}; use rustc_span::Span; diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index c571ac507248..e3eea83ba49a 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -1,3 +1,4 @@ +use rustc_macros::HashStable; use smallvec::SmallVec; use crate::ty::context::TyCtxt; diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 4002d0da7909..a08fde976bc1 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -8,7 +8,9 @@ use rustc_hir::def::Namespace; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::lang_items::LangItem; use rustc_index::bit_set::FiniteBitSet; -use rustc_macros::HashStable; +use rustc_macros::{ + Decodable, Encodable, HashStable, Lift, TyDecodable, TyEncodable, TypeVisitable, +}; use rustc_middle::ty::normalize_erasing_regions::NormalizationError; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::Symbol; diff --git a/compiler/rustc_middle/src/ty/intrinsic.rs b/compiler/rustc_middle/src/ty/intrinsic.rs index 18d08ed23a5e..68c1d8c17ec1 100644 --- a/compiler/rustc_middle/src/ty/intrinsic.rs +++ b/compiler/rustc_middle/src/ty/intrinsic.rs @@ -1,3 +1,4 @@ +use rustc_macros::{Decodable, Encodable, HashStable}; use rustc_span::{def_id::DefId, Symbol}; use super::TyCtxt; diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 897d6f5662f6..189b95becfb5 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -10,6 +10,7 @@ use rustc_errors::{ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_index::IndexVec; +use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable}; use rustc_session::config::OptLevel; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP}; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 094b68ce5ad3..3c73316865db 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -47,7 +47,9 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; use rustc_index::IndexVec; -use rustc_macros::HashStable; +use rustc_macros::{ + Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, +}; use rustc_query_system::ich::StableHashingContext; use rustc_serialize::{Decodable, Encodable}; use rustc_session::lint::LintBuffer; diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 585436744602..791f27a97896 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -10,6 +10,7 @@ use crate::traits::query::NoSolution; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder}; use crate::ty::{self, EarlyBinder, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt}; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; #[derive(Debug, Copy, Clone, HashStable, TyEncodable, TyDecodable)] pub enum NormalizationError<'tcx> { diff --git a/compiler/rustc_middle/src/ty/pattern.rs b/compiler/rustc_middle/src/ty/pattern.rs index 8a41ba257ec6..d1875fbaea37 100644 --- a/compiler/rustc_middle/src/ty/pattern.rs +++ b/compiler/rustc_middle/src/ty/pattern.rs @@ -2,6 +2,7 @@ use std::fmt; use crate::ty; use rustc_data_structures::intern::Interned; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)] #[rustc_pass_by_value] diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 05156dd5205e..56dd52567fde 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -3,6 +3,7 @@ use rustc_data_structures::intern::Interned; use rustc_errors::{DiagArgValue, IntoDiagArg}; use rustc_hir::def_id::DefId; use rustc_hir::LangItem; +use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_span::Span; use rustc_type_ir::ClauseKind as IrClauseKind; use rustc_type_ir::PredicateKind as IrPredicateKind; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index e5450182bf29..5f47aef0f32c 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -16,6 +16,7 @@ use rustc_hir::def::{self, CtorKind, DefKind, Namespace}; use rustc_hir::def_id::{DefIdMap, DefIdSet, ModDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPathDataName}; use rustc_hir::LangItem; +use rustc_macros::Lift; use rustc_session::cstore::{ExternCrate, ExternCrateSource}; use rustc_session::Limit; use rustc_span::symbol::{kw, Ident, Symbol}; diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index b92800a17288..3d9be15310fe 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -3,6 +3,7 @@ use rustc_data_structures::intern::Interned; use rustc_errors::MultiSpan; use rustc_hir::def_id::DefId; use rustc_index::Idx; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_span::symbol::sym; use rustc_span::symbol::{kw, Symbol}; use rustc_span::{ErrorGuaranteed, DUMMY_SP}; diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 3c1dea1d9f24..7063ef07201b 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -10,6 +10,7 @@ use crate::ty::{GenericArg, GenericArgKind, GenericArgsRef}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; +use rustc_macros::TypeVisitable; use rustc_target::spec::abi; use std::iter; diff --git a/compiler/rustc_middle/src/ty/rvalue_scopes.rs b/compiler/rustc_middle/src/ty/rvalue_scopes.rs index 17eabec257e9..cb2f7284eaa0 100644 --- a/compiler/rustc_middle/src/ty/rvalue_scopes.rs +++ b/compiler/rustc_middle/src/ty/rvalue_scopes.rs @@ -1,6 +1,7 @@ use crate::middle::region::{Scope, ScopeData, ScopeTree}; use rustc_hir as hir; use rustc_hir::ItemLocalMap; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; /// `RvalueScopes` is a mapping from sub-expressions to _extended_ lifetime as determined by /// rules laid out in `rustc_hir_analysis::check::rvalue_scopes`. diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 0184ff549795..d9350f36d33d 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -17,7 +17,7 @@ use rustc_errors::{DiagArgValue, ErrorGuaranteed, IntoDiagArg, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::LangItem; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index e06e3465eb2a..cf5decffea92 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -8,7 +8,7 @@ use std::iter; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::ErrorGuaranteed; -use rustc_macros::HashStable; +use rustc_macros::{Decodable, Encodable, HashStable}; /// A trait's definition with type information. #[derive(HashStable, Encodable, Decodable)] diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 0c4409197bbc..41f417dfd4b1 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -18,7 +18,7 @@ use rustc_hir::{ BindingMode, ByRef, HirId, ItemLocalId, ItemLocalMap, ItemLocalSet, Mutability, }; use rustc_index::IndexVec; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_middle::mir::FakeReadCause; use rustc_session::Session; use rustc_span::Span; diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 42e0565db83d..ae0de08f02fa 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -17,7 +17,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; use rustc_index::bit_set::GrowableBitSet; -use rustc_macros::HashStable; +use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable}; use rustc_session::Limit; use rustc_span::sym; use rustc_target::abi::{Integer, IntegerType, Primitive, Size}; diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs index 62f41921d888..2ad194313100 100644 --- a/compiler/rustc_middle/src/ty/vtable.rs +++ b/compiler/rustc_middle/src/ty/vtable.rs @@ -3,6 +3,7 @@ use std::fmt; use crate::mir::interpret::{alloc_range, AllocId, Allocation, Pointer, Scalar}; use crate::ty::{self, Instance, PolyTraitRef, Ty, TyCtxt}; use rustc_ast::Mutability; +use rustc_macros::HashStable; #[derive(Clone, Copy, PartialEq, HashStable)] pub enum VtblEntry<'tcx> { From 254a9fbe86a4a6d3c0481f7924c4b0393e1a230e Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Mon, 29 Apr 2024 08:16:26 +0530 Subject: [PATCH 142/279] Prohibit const prop of unions in `KnownPanicsLint` as they have a potential to ICE during layout calculation --- .../src/known_panics_lint.rs | 20 ++++++++----- tests/crashes/123710.rs | 17 ----------- ...st-prop-unions-known-panics-lint-123710.rs | 22 ++++++++++++++ ...rop-unions-known-panics-lint-123710.stderr | 29 +++++++++++++++++++ 4 files changed, 64 insertions(+), 24 deletions(-) delete mode 100644 tests/crashes/123710.rs create mode 100644 tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.rs create mode 100644 tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.stderr diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index b8dbf8a759fc..b2030efca8f0 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -896,13 +896,19 @@ impl CanConstProp { }; for (local, val) in cpv.can_const_prop.iter_enumerated_mut() { let ty = body.local_decls[local].ty; - match tcx.layout_of(param_env.and(ty)) { - Ok(layout) if layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) => {} - // Either the layout fails to compute, then we can't use this local anyway - // or the local is too large, then we don't want to. - _ => { - *val = ConstPropMode::NoPropagation; - continue; + if ty.is_union() { + // Do not const prop unions as they can + // ICE during layout calc + *val = ConstPropMode::NoPropagation; + } else { + match tcx.layout_of(param_env.and(ty)) { + Ok(layout) if layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) => {} + // Either the layout fails to compute, then we can't use this local anyway + // or the local is too large, then we don't want to. + _ => { + *val = ConstPropMode::NoPropagation; + continue; + } } } } diff --git a/tests/crashes/123710.rs b/tests/crashes/123710.rs deleted file mode 100644 index f171fa7cebb4..000000000000 --- a/tests/crashes/123710.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: #123710 - -#[repr(packed)] -#[repr(u32)] -enum E { - A, - B, - C, -} - -fn main() { - union InvalidTag { - int: u32, - e: E, - } - let _invalid_tag = InvalidTag { int: 4 }; -} diff --git a/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.rs b/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.rs new file mode 100644 index 000000000000..2b93d0f8a609 --- /dev/null +++ b/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.rs @@ -0,0 +1,22 @@ +// Regression test for issue 123710. +// Tests that the we do not ICE in KnownPanicsLint +// when a union contains an enum with an repr(packed), +// which is a repr not supported for enums + +#[repr(packed)] +//~^ ERROR attribute should be applied to a struct or union +#[repr(u32)] +enum E { + A, + B, + C, +} + +fn main() { + union InvalidTag { + int: u32, + e: E, +//~^ ERROR field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union + } + let _invalid_tag = InvalidTag { int: 4 }; +} diff --git a/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.stderr b/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.stderr new file mode 100644 index 000000000000..44dde6120e8d --- /dev/null +++ b/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.stderr @@ -0,0 +1,29 @@ +error[E0517]: attribute should be applied to a struct or union + --> $DIR/ice-const-prop-unions-known-panics-lint-123710.rs:6:8 + | +LL | #[repr(packed)] + | ^^^^^^ +... +LL | / enum E { +LL | | A, +LL | | B, +LL | | C, +LL | | } + | |_- not a struct or union + +error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union + --> $DIR/ice-const-prop-unions-known-panics-lint-123710.rs:18:9 + | +LL | e: E, + | ^^^^ + | + = note: union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>` +help: wrap the field type in `ManuallyDrop<...>` + | +LL | e: std::mem::ManuallyDrop, + | +++++++++++++++++++++++ + + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0517, E0740. +For more information about an error, try `rustc --explain E0517`. From e6b3e20243ba3d8dd4f369bfc286599796680e1d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 29 Apr 2024 13:42:13 +1000 Subject: [PATCH 143/279] Remove `extern crate rustc_session` from `rustc_lint`. --- compiler/rustc_lint/src/array_into_iter.rs | 1 + compiler/rustc_lint/src/async_fn_in_trait.rs | 1 + compiler/rustc_lint/src/builtin.rs | 1 + compiler/rustc_lint/src/deref_into_dyn_supertrait.rs | 1 + compiler/rustc_lint/src/drop_forget_useless.rs | 1 + compiler/rustc_lint/src/enum_intrinsics_non_enums.rs | 1 + compiler/rustc_lint/src/for_loops_over_fallibles.rs | 1 + compiler/rustc_lint/src/foreign_modules.rs | 1 + compiler/rustc_lint/src/hidden_unicode_codepoints.rs | 1 + compiler/rustc_lint/src/invalid_from_utf8.rs | 1 + compiler/rustc_lint/src/let_underscore.rs | 1 + compiler/rustc_lint/src/lib.rs | 2 -- compiler/rustc_lint/src/map_unit_fn.rs | 1 + compiler/rustc_lint/src/methods.rs | 1 + compiler/rustc_lint/src/multiple_supertrait_upcastable.rs | 1 + compiler/rustc_lint/src/non_ascii_idents.rs | 1 + compiler/rustc_lint/src/non_fmt_panic.rs | 1 + compiler/rustc_lint/src/non_local_def.rs | 1 + compiler/rustc_lint/src/nonstandard_style.rs | 1 + compiler/rustc_lint/src/noop_method_call.rs | 1 + compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs | 1 + compiler/rustc_lint/src/pass_by_value.rs | 1 + compiler/rustc_lint/src/redundant_semicolon.rs | 1 + compiler/rustc_lint/src/reference_casting.rs | 1 + compiler/rustc_lint/src/traits.rs | 1 + compiler/rustc_lint/src/types.rs | 1 + compiler/rustc_lint/src/unit_bindings.rs | 1 + compiler/rustc_lint/src/unused.rs | 1 + 28 files changed, 27 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_lint/src/array_into_iter.rs b/compiler/rustc_lint/src/array_into_iter.rs index 3a5c585366a3..ce5f3052e2a5 100644 --- a/compiler/rustc_lint/src/array_into_iter.rs +++ b/compiler/rustc_lint/src/array_into_iter.rs @@ -6,6 +6,7 @@ use rustc_hir as hir; use rustc_middle::ty; use rustc_middle::ty::adjustment::{Adjust, Adjustment}; use rustc_session::lint::FutureIncompatibilityReason; +use rustc_session::{declare_lint, impl_lint_pass}; use rustc_span::edition::Edition; use rustc_span::symbol::sym; use rustc_span::Span; diff --git a/compiler/rustc_lint/src/async_fn_in_trait.rs b/compiler/rustc_lint/src/async_fn_in_trait.rs index 5f7a3137d52d..40778542c75c 100644 --- a/compiler/rustc_lint/src/async_fn_in_trait.rs +++ b/compiler/rustc_lint/src/async_fn_in_trait.rs @@ -2,6 +2,7 @@ use crate::lints::AsyncFnInTraitDiag; use crate::LateContext; use crate::LateLintPass; use rustc_hir as hir; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_trait_selection::traits::error_reporting::suggestions::suggest_desugaring_async_fn_to_impl_future_in_trait; declare_lint! { diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 0c89e186c47e..9b7e740d883e 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -59,6 +59,7 @@ use rustc_middle::ty::ToPredicate; use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef}; use rustc_session::lint::{BuiltinLintDiag, FutureIncompatibilityReason}; +use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass}; use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs index 9bc81d2c46aa..b671dfaa0d1b 100644 --- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs +++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs @@ -6,6 +6,7 @@ use crate::{ use rustc_hir as hir; use rustc_middle::ty; use rustc_session::lint::FutureIncompatibilityReason; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::sym; use rustc_trait_selection::traits::supertraits; diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs index 78ac7f9b2354..60b799f3c746 100644 --- a/compiler/rustc_lint/src/drop_forget_useless.rs +++ b/compiler/rustc_lint/src/drop_forget_useless.rs @@ -1,5 +1,6 @@ use rustc_hir::{Arm, Expr, ExprKind, Node}; use rustc_middle::ty; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::sym; use crate::{ diff --git a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs index a67f1b62fb0d..958da177eda5 100644 --- a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs +++ b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs @@ -5,6 +5,7 @@ use crate::{ }; use rustc_hir as hir; use rustc_middle::ty::{visit::TypeVisitableExt, Ty}; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::{symbol::sym, Span}; declare_lint! { diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs index cb7feea16b53..ce3f45a17e9f 100644 --- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs +++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs @@ -10,6 +10,7 @@ use hir::{Expr, Pat}; use rustc_hir as hir; use rustc_infer::{infer::TyCtxtInferExt, traits::ObligationCause}; use rustc_middle::ty::{self, List}; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::{sym, Span}; use rustc_trait_selection::traits::ObligationCtxt; diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index fae492f252e5..48e5683fc0a9 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -5,6 +5,7 @@ use rustc_hir::def::DefKind; use rustc_middle::query::Providers; use rustc_middle::ty::layout::LayoutError; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; +use rustc_session::declare_lint; use rustc_span::{sym, Span, Symbol}; use rustc_target::abi::FIRST_VARIANT; diff --git a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs index 054cfe92a3a4..aa8ca1776dc0 100644 --- a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs +++ b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs @@ -7,6 +7,7 @@ use crate::{ }; use ast::util::unicode::{contains_text_flow_control_chars, TEXT_FLOW_CONTROL_CHARS}; use rustc_ast as ast; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::{BytePos, Span, Symbol}; declare_lint! { diff --git a/compiler/rustc_lint/src/invalid_from_utf8.rs b/compiler/rustc_lint/src/invalid_from_utf8.rs index 081e3e875302..0081374922e6 100644 --- a/compiler/rustc_lint/src/invalid_from_utf8.rs +++ b/compiler/rustc_lint/src/invalid_from_utf8.rs @@ -2,6 +2,7 @@ use std::str::Utf8Error; use rustc_ast::LitKind; use rustc_hir::{Expr, ExprKind}; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::source_map::Spanned; use rustc_span::sym; diff --git a/compiler/rustc_lint/src/let_underscore.rs b/compiler/rustc_lint/src/let_underscore.rs index 9d4d75a646ae..ea82fb9f2625 100644 --- a/compiler/rustc_lint/src/let_underscore.rs +++ b/compiler/rustc_lint/src/let_underscore.rs @@ -5,6 +5,7 @@ use crate::{ use rustc_errors::MultiSpan; use rustc_hir as hir; use rustc_middle::ty; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::{sym, Symbol}; declare_lint! { diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index e00d8c1e6bd9..901c9b19ba35 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -42,8 +42,6 @@ #[macro_use] extern crate rustc_middle; #[macro_use] -extern crate rustc_session; -#[macro_use] extern crate tracing; mod array_into_iter; diff --git a/compiler/rustc_lint/src/map_unit_fn.rs b/compiler/rustc_lint/src/map_unit_fn.rs index 07980cfb6fa0..e355604e2068 100644 --- a/compiler/rustc_lint/src/map_unit_fn.rs +++ b/compiler/rustc_lint/src/map_unit_fn.rs @@ -6,6 +6,7 @@ use rustc_middle::{ query::Key, ty::{self, Ty}, }; +use rustc_session::{declare_lint, declare_lint_pass}; declare_lint! { /// The `map_unit_fn` lint checks for `Iterator::map` receive diff --git a/compiler/rustc_lint/src/methods.rs b/compiler/rustc_lint/src/methods.rs index 9cfdaf0ce2ff..b93245d58d9d 100644 --- a/compiler/rustc_lint/src/methods.rs +++ b/compiler/rustc_lint/src/methods.rs @@ -4,6 +4,7 @@ use crate::LateLintPass; use crate::LintContext; use rustc_hir::{Expr, ExprKind}; use rustc_middle::ty; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::{symbol::sym, Span}; declare_lint! { diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs index 69d623b547b5..48d140c6b7f3 100644 --- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs +++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs @@ -1,6 +1,7 @@ use crate::{LateContext, LateLintPass, LintContext}; use rustc_hir as hir; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::sym; declare_lint! { diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs index 79bc78ae55a8..9f298a6071c6 100644 --- a/compiler/rustc_lint/src/non_ascii_idents.rs +++ b/compiler/rustc_lint/src/non_ascii_idents.rs @@ -6,6 +6,7 @@ use crate::{EarlyContext, EarlyLintPass, LintContext}; use rustc_ast as ast; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::UnordMap; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::symbol::Symbol; use unicode_security::general_security_profile::IdentifierType; diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index e81790a7348e..6527e10c580f 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -8,6 +8,7 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::ty; use rustc_parse_format::{ParseMode, Parser, Piece}; use rustc_session::lint::FutureIncompatibilityReason; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::edition::Edition; use rustc_span::{hygiene, sym, symbol::kw, InnerSpan, Span, Symbol}; use rustc_trait_selection::infer::InferCtxtExt; diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 004c2c2e4f44..438a35a80abc 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -5,6 +5,7 @@ use rustc_infer::infer::InferCtxt; use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_middle::ty::{self, Binder, Ty, TyCtxt, TypeFoldable, TypeFolder}; use rustc_middle::ty::{EarlyBinder, TraitRef, TypeSuperFoldable}; +use rustc_session::{declare_lint, impl_lint_pass}; use rustc_span::def_id::{DefId, LOCAL_CRATE}; use rustc_span::Span; use rustc_span::{sym, symbol::kw, ExpnKind, MacroKind}; diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index ee863672017d..dbb0644cd63f 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -11,6 +11,7 @@ use rustc_hir::intravisit::FnKind; use rustc_hir::{GenericParamKind, PatKind}; use rustc_middle::ty; use rustc_session::config::CrateType; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::{sym, Ident}; use rustc_span::{BytePos, Span}; diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs index 970d411fb065..91441248e70f 100644 --- a/compiler/rustc_lint/src/noop_method_call.rs +++ b/compiler/rustc_lint/src/noop_method_call.rs @@ -8,6 +8,7 @@ use rustc_hir::def::DefKind; use rustc_hir::{Expr, ExprKind}; use rustc_middle::ty; use rustc_middle::ty::adjustment::Adjust; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::symbol::sym; declare_lint! { diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index ec7954536bec..1ea1f496e508 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -4,6 +4,7 @@ use rustc_macros::{LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{ self, fold::BottomUpFolder, print::TraitPredPrintModifiersAndPath, Ty, TypeFoldable, }; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::{symbol::kw, Span}; use rustc_trait_selection::traits; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs index 160d42caa9e2..1f0a8a0b5678 100644 --- a/compiler/rustc_lint/src/pass_by_value.rs +++ b/compiler/rustc_lint/src/pass_by_value.rs @@ -4,6 +4,7 @@ use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::{GenericArg, PathSegment, QPath, TyKind}; use rustc_middle::ty; +use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::sym; declare_tool_lint! { diff --git a/compiler/rustc_lint/src/redundant_semicolon.rs b/compiler/rustc_lint/src/redundant_semicolon.rs index 1681ac2f1e5a..ef08e79e24a0 100644 --- a/compiler/rustc_lint/src/redundant_semicolon.rs +++ b/compiler/rustc_lint/src/redundant_semicolon.rs @@ -1,5 +1,6 @@ use crate::{lints::RedundantSemicolonsDiag, EarlyContext, EarlyLintPass, LintContext}; use rustc_ast::{Block, StmtKind}; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::Span; declare_lint! { diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index 9b938b34c00a..9fed91f72628 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -2,6 +2,7 @@ use rustc_ast::Mutability; use rustc_hir::{Expr, ExprKind, UnOp}; use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::{self, layout::TyAndLayout}; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::sym; use crate::{lints::InvalidReferenceCastingDiag, LateContext, LateLintPass, LintContext}; diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs index 789f154eac5b..4d1b1dc4fb78 100644 --- a/compiler/rustc_lint/src/traits.rs +++ b/compiler/rustc_lint/src/traits.rs @@ -3,6 +3,7 @@ use crate::LateContext; use crate::LateLintPass; use crate::LintContext; use rustc_hir as hir; +use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::symbol::sym; declare_lint! { diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index e982842f5363..ff4e3141f1f1 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -22,6 +22,7 @@ use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{ self, AdtKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, }; +use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass}; use rustc_span::def_id::LocalDefId; use rustc_span::source_map; use rustc_span::symbol::sym; diff --git a/compiler/rustc_lint/src/unit_bindings.rs b/compiler/rustc_lint/src/unit_bindings.rs index 6222adf58ae7..137e0dcb330a 100644 --- a/compiler/rustc_lint/src/unit_bindings.rs +++ b/compiler/rustc_lint/src/unit_bindings.rs @@ -2,6 +2,7 @@ use crate::lints::UnitBindingsDiag; use crate::{LateLintPass, LintContext}; use rustc_hir as hir; use rustc_middle::ty::Ty; +use rustc_session::{declare_lint, declare_lint_pass}; declare_lint! { /// The `unit_bindings` lint detects cases where bindings are useless because they have diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 0b0949e4dd86..a080e9ba82ba 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -16,6 +16,7 @@ use rustc_hir::def_id::DefId; use rustc_infer::traits::util::elaborate; use rustc_middle::ty::adjustment; use rustc_middle::ty::{self, Ty}; +use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass}; use rustc_span::symbol::Symbol; use rustc_span::symbol::{kw, sym}; use rustc_span::{BytePos, Span}; From 448d527fd8d705393274198d858a4e2d2a2d8d54 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Mon, 29 Apr 2024 06:49:39 +0200 Subject: [PATCH 144/279] Typo fix: exec:ing -> exec'ing --- tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs index 694fa460e9bb..3e63349edb74 100644 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs +++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs @@ -8,7 +8,7 @@ extern crate libc; -// By default the Rust runtime resets SIGPIPE to SIG_DFL before exec:ing child +// By default the Rust runtime resets SIGPIPE to SIG_DFL before exec'ing child // processes so opt-out of that with `#[unix_sigpipe = "sig_dfl"]`. See // https://github.com/rust-lang/rust/blob/bf4de3a874753bbee3323081c8b0c133444fed2d/library/std/src/sys/pal/unix/process/process_unix.rs#L359-L384 #[unix_sigpipe = "sig_dfl"] From de3eff79a6456aa3f31e37123e73ef713d00f781 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Mon, 29 Apr 2024 06:50:38 +0200 Subject: [PATCH 145/279] aux-bin: Avoid old .so files from old tests; clean auxiliary dir root --- src/tools/compiletest/src/runtest.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index b0f84b1162f4..da51b33a9d6d 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2140,6 +2140,7 @@ impl<'test> TestCx<'test> { if !self.props.aux_bins.is_empty() { let aux_bin_dir = self.aux_bin_output_dir_name(); + remove_and_create_dir_all(&aux_dir); remove_and_create_dir_all(&aux_bin_dir); } From 99e036bd21a542a06a58f8867186b38157e25b66 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 29 Apr 2024 13:56:41 +1000 Subject: [PATCH 146/279] Remove `extern crate rustc_middle` from numerous crates. --- compiler/rustc_borrowck/src/borrow_set.rs | 1 + compiler/rustc_borrowck/src/borrowck_errors.rs | 1 + compiler/rustc_borrowck/src/def_use.rs | 1 + compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs | 1 + compiler/rustc_borrowck/src/diagnostics/mod.rs | 1 + compiler/rustc_borrowck/src/diagnostics/move_errors.rs | 1 + compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs | 1 + compiler/rustc_borrowck/src/diagnostics/region_errors.rs | 1 + compiler/rustc_borrowck/src/diagnostics/region_name.rs | 1 + compiler/rustc_borrowck/src/lib.rs | 3 +-- compiler/rustc_borrowck/src/places_conflict.rs | 1 + compiler/rustc_borrowck/src/polonius/loan_invalidations.rs | 1 + compiler/rustc_borrowck/src/region_infer/mod.rs | 1 + compiler/rustc_borrowck/src/type_check/canonical.rs | 1 + .../rustc_borrowck/src/type_check/constraint_conversion.rs | 1 + compiler/rustc_borrowck/src/type_check/liveness/mod.rs | 1 + compiler/rustc_borrowck/src/type_check/mod.rs | 1 + compiler/rustc_borrowck/src/type_check/relate_tys.rs | 1 + compiler/rustc_borrowck/src/universal_regions.rs | 1 + compiler/rustc_codegen_ssa/src/back/link.rs | 1 + compiler/rustc_codegen_ssa/src/back/linker.rs | 1 + compiler/rustc_codegen_ssa/src/back/metadata.rs | 1 + compiler/rustc_codegen_ssa/src/back/symbol_export.rs | 1 + compiler/rustc_codegen_ssa/src/back/write.rs | 1 + compiler/rustc_codegen_ssa/src/base.rs | 1 + compiler/rustc_codegen_ssa/src/common.rs | 1 + compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs | 1 + compiler/rustc_codegen_ssa/src/lib.rs | 2 -- compiler/rustc_codegen_ssa/src/meth.rs | 1 + compiler/rustc_codegen_ssa/src/mir/analyze.rs | 1 + compiler/rustc_codegen_ssa/src/mir/block.rs | 1 + compiler/rustc_codegen_ssa/src/mir/constant.rs | 1 + compiler/rustc_codegen_ssa/src/mir/debuginfo.rs | 1 + compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 1 + compiler/rustc_codegen_ssa/src/mir/mod.rs | 1 + compiler/rustc_codegen_ssa/src/mir/operand.rs | 1 + compiler/rustc_codegen_ssa/src/mir/place.rs | 1 + compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 4 ++-- compiler/rustc_codegen_ssa/src/mir/statement.rs | 4 ++-- compiler/rustc_codegen_ssa/src/mono_item.rs | 1 + compiler/rustc_codegen_ssa/src/size_of_val.rs | 1 + compiler/rustc_codegen_ssa/src/target_features.rs | 1 + compiler/rustc_codegen_ssa/src/traits/type_.rs | 1 + compiler/rustc_incremental/src/assert_dep_graph.rs | 1 + compiler/rustc_incremental/src/lib.rs | 2 -- compiler/rustc_incremental/src/persist/fs.rs | 1 + compiler/rustc_lint/src/array_into_iter.rs | 1 + compiler/rustc_lint/src/builtin.rs | 1 + compiler/rustc_lint/src/context.rs | 1 + compiler/rustc_lint/src/context/diagnostics/check_cfg.rs | 1 + compiler/rustc_lint/src/levels.rs | 1 + compiler/rustc_lint/src/lib.rs | 2 -- compiler/rustc_lint/src/non_fmt_panic.rs | 1 + compiler/rustc_lint/src/types.rs | 1 + compiler/rustc_mir_dataflow/src/elaborate_drops.rs | 1 + compiler/rustc_mir_dataflow/src/framework/engine.rs | 1 + compiler/rustc_mir_dataflow/src/impls/initialized.rs | 1 + compiler/rustc_mir_dataflow/src/lib.rs | 2 -- compiler/rustc_mir_dataflow/src/move_paths/builder.rs | 1 + compiler/rustc_mir_dataflow/src/value_analysis.rs | 1 + compiler/rustc_monomorphize/src/collector.rs | 1 + compiler/rustc_monomorphize/src/lib.rs | 3 +-- compiler/rustc_monomorphize/src/partitioning.rs | 1 + compiler/rustc_passes/src/abi_test.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 1 + compiler/rustc_passes/src/check_const.rs | 1 + compiler/rustc_passes/src/dead.rs | 1 + compiler/rustc_passes/src/layout_test.rs | 1 + compiler/rustc_passes/src/lib.rs | 2 -- compiler/rustc_passes/src/liveness.rs | 1 + compiler/rustc_passes/src/loops.rs | 1 + compiler/rustc_passes/src/reachable.rs | 1 + compiler/rustc_pattern_analysis/src/lib.rs | 3 --- compiler/rustc_pattern_analysis/src/rustc.rs | 1 + compiler/rustc_symbol_mangling/src/legacy.rs | 1 + compiler/rustc_symbol_mangling/src/lib.rs | 3 --- compiler/rustc_symbol_mangling/src/v0.rs | 1 + compiler/rustc_traits/src/codegen.rs | 1 + compiler/rustc_traits/src/dropck_outlives.rs | 1 + compiler/rustc_traits/src/lib.rs | 2 -- 80 files changed, 74 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrow_set.rs b/compiler/rustc_borrowck/src/borrow_set.rs index af5f75710743..0afe36fec441 100644 --- a/compiler/rustc_borrowck/src/borrow_set.rs +++ b/compiler/rustc_borrowck/src/borrow_set.rs @@ -6,6 +6,7 @@ use rustc_index::bit_set::BitSet; use rustc_middle::mir::traversal; use rustc_middle::mir::visit::{MutatingUseContext, NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{self, Body, Local, Location}; +use rustc_middle::span_bug; use rustc_middle::ty::{RegionVid, TyCtxt}; use rustc_mir_dataflow::move_paths::MoveData; use std::fmt; diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 6b576ba3c4cc..622feb4e4c73 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -2,6 +2,7 @@ #![allow(rustc::untranslatable_diagnostic)] use rustc_errors::{codes::*, struct_span_code_err, Diag, DiagCtxt}; +use rustc_middle::span_bug; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs index 6fd80d005d9e..1f0b0981c8f2 100644 --- a/compiler/rustc_borrowck/src/def_use.rs +++ b/compiler/rustc_borrowck/src/def_use.rs @@ -1,3 +1,4 @@ +use rustc_middle::bug; use rustc_middle::mir::visit::{ MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, }; diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index da58db575252..6c82dd1489ca 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -13,6 +13,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{walk_block, walk_expr, Map, Visitor}; use rustc_hir::{CoroutineDesugaring, PatField}; use rustc_hir::{CoroutineKind, CoroutineSource, LangItem}; +use rustc_middle::bug; use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 6224cda1b169..0b4018a23ce7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -12,6 +12,7 @@ use rustc_hir::CoroutineKind; use rustc_index::IndexSlice; use rustc_infer::infer::BoundRegionConversionTime; use rustc_infer::traits::{FulfillmentErrorCode, SelectionError}; +use rustc_middle::bug; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ AggregateKind, CallSource, ConstOperand, FakeReadCause, Local, LocalInfo, LocalKind, Location, diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 288b846daf56..1d844c3d6a29 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -4,6 +4,7 @@ use rustc_errors::{Applicability, Diag}; use rustc_hir::intravisit::Visitor; use rustc_hir::{CaptureBy, ExprKind, HirId, Node}; +use rustc_middle::bug; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty}; use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex}; diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 8b3142171908..5d74a01aa207 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -7,6 +7,7 @@ use rustc_errors::{Applicability, Diag}; use rustc_hir::intravisit::Visitor; use rustc_hir::{self as hir, BindingMode, ByRef, Node}; use rustc_infer::traits; +use rustc_middle::bug; use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem}; use rustc_middle::ty::{self, InstanceDef, ToPredicate, Ty, TyCtxt}; use rustc_middle::{ diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 2fe75fe2a2bf..d8d582b0ad1c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -18,6 +18,7 @@ use rustc_infer::infer::{ error_reporting::unexpected_hidden_region_diagnostic, NllRegionVariableOrigin, RelateParamBound, }; +use rustc_middle::bug; use rustc_middle::hir::place::PlaceBase; use rustc_middle::mir::{ConstraintCategory, ReturnConstraint}; use rustc_middle::ty::GenericArgs; diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index cda613604041..28c5c505f791 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -11,6 +11,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_middle::ty::print::RegionHighlightMode; use rustc_middle::ty::{self, RegionVid, Ty}; use rustc_middle::ty::{GenericArgKind, GenericArgsRef}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 60037d28f620..2da8ff240c6e 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -14,8 +14,6 @@ #![feature(stmt_expr_attributes)] #![feature(try_blocks)] -#[macro_use] -extern crate rustc_middle; #[macro_use] extern crate tracing; @@ -33,6 +31,7 @@ use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::*; use rustc_middle::query::Providers; use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::UNUSED_MUT; use rustc_span::{Span, Symbol}; use rustc_target::abi::FieldIdx; diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs index c559f9d57481..ad3c3e6d0793 100644 --- a/compiler/rustc_borrowck/src/places_conflict.rs +++ b/compiler/rustc_borrowck/src/places_conflict.rs @@ -54,6 +54,7 @@ use crate::ArtificialField; use crate::Overlap; use crate::{AccessDepth, Deep, Shallow}; use rustc_hir as hir; +use rustc_middle::bug; use rustc_middle::mir::{ Body, BorrowKind, FakeBorrowKind, MutBorrowKind, Place, PlaceElem, PlaceRef, ProjectionElem, }; diff --git a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs index de469080d14e..a1e59977ede5 100644 --- a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs +++ b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs @@ -1,4 +1,5 @@ use rustc_data_structures::graph::dominators::Dominators; +use rustc_middle::bug; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::{ self, BasicBlock, Body, FakeBorrowKind, Location, NonDivergingIntrinsic, Place, Rvalue, diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index dd75548a15df..78465ad7975d 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -11,6 +11,7 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_infer::infer::outlives::test_type_match; use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin}; +use rustc_middle::bug; use rustc_middle::mir::{ BasicBlock, Body, ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureOutlivesSubjectTy, ClosureRegionRequirements, ConstraintCategory, Local, Location, ReturnConstraint, diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index a950f10787b3..49d3f7381d91 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -2,6 +2,7 @@ use std::fmt; use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::canonical::Canonical; +use rustc_middle::bug; use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable}; use rustc_span::def_id::DefId; diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index de75a9857f8b..5aa8fe213814 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -4,6 +4,7 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate}; use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound}; use rustc_infer::infer::{self, InferCtxt, SubregionOrigin}; +use rustc_middle::bug; use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory}; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::ObligationCause; diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs index 51ae7d14e438..38ec9f7678eb 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs @@ -2,6 +2,7 @@ use itertools::{Either, Itertools}; use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir::visit::{TyContext, Visitor}; use rustc_middle::mir::{Body, Local, Location, SourceInfo}; +use rustc_middle::span_bug; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{GenericArgsRef, Region, RegionVid, Ty, TyCtxt}; use rustc_mir_dataflow::impls::MaybeInitializedPlaces; diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 61fa84666744..b67c5d858183 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -33,6 +33,7 @@ use rustc_middle::ty::{ OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, }; use rustc_middle::ty::{GenericArgsRef, UserArgs}; +use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::points::DenseLocationMap; use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::source_map::Spanned; diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index d67ede57e787..5e4b3e532c41 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -5,6 +5,7 @@ use rustc_infer::infer::NllRegionVariableOrigin; use rustc_infer::infer::{ObligationEmittingRelation, StructurallyRelateAliases}; use rustc_infer::traits::{Obligation, PredicateObligations}; use rustc_middle::mir::ConstraintCategory; +use rustc_middle::span_bug; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::fold::FnMutDelegate; diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 9c65f64b03fe..070238fc3788 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -27,6 +27,7 @@ use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty, TyCtxt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::{kw, sym}; use rustc_span::Symbol; use std::iter; diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index b458f325b737..1f691d14c532 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -8,6 +8,7 @@ use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize}; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_metadata::find_native_static_library; use rustc_metadata::fs::{copy_to_stdout, emit_wrapper_file, METADATA_FILENAME}; +use rustc_middle::bug; use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::exported_symbols::SymbolExportKind; diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 85fcc4f4f404..f85056f8ad41 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -12,6 +12,7 @@ use std::{env, mem, str}; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_metadata::find_native_static_library; +use rustc_middle::bug; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::exported_symbols; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportKind}; diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index ab1bc0b6cd2e..264a98844ad6 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -16,6 +16,7 @@ use rustc_data_structures::owned_slice::{try_slice_owned, OwnedSlice}; use rustc_metadata::creader::MetadataLoader; use rustc_metadata::fs::METADATA_FILENAME; use rustc_metadata::EncodedMetadata; +use rustc_middle::bug; use rustc_session::Session; use rustc_span::sym; use rustc_target::abi::Endian; diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index cce3f0e6f2d1..0e335bf00cf0 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -6,6 +6,7 @@ use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE} use rustc_data_structures::unord::UnordMap; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE}; +use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::exported_symbols::{ metadata_symbol_name, ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel, diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index c4f062405bb5..53ba0da7d049 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -26,6 +26,7 @@ use rustc_incremental::{ }; use rustc_metadata::fs::copy_to_stdout; use rustc_metadata::EncodedMetadata; +use rustc_middle::bug; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::middle::exported_symbols::SymbolExportInfo; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index ae7c0f24b40f..358c24bfb823 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -24,6 +24,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::lang_items::LangItem; use rustc_metadata::EncodedMetadata; +use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, DebuggerVisualizerType}; use rustc_middle::middle::exported_symbols; diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index b41739867c7d..e4a36b3f5918 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -4,6 +4,7 @@ use rustc_hir::LangItem; use rustc_middle::mir; use rustc_middle::ty::Instance; use rustc_middle::ty::{self, layout::TyAndLayout, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_span::Span; use crate::traits::*; diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 5f0dcf9510f9..e9c7606dc5a8 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -16,6 +16,7 @@ use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; use rustc_hir::def_id::DefId; use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData}; use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Mutability}; +use rustc_middle::bug; use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; use rustc_middle::ty::{self, ExistentialProjection, ParamEnv, Ty, TyCtxt}; use rustc_middle::ty::{GenericArgKind, GenericArgsRef}; diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index be91fe8480cd..46e1410a509a 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -18,8 +18,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; use rustc_ast as ast; use rustc_data_structures::fx::FxHashSet; diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index 4f7dc9968a13..23036e9bea02 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -1,5 +1,6 @@ use crate::traits::*; +use rustc_middle::bug; use rustc_middle::ty::{self, GenericArgKind, Ty}; use rustc_session::config::Lto; use rustc_symbol_mangling::typeid_for_trait_ref; diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index c1de9b76fe73..09ae7cf64109 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -10,6 +10,7 @@ use rustc_middle::mir::traversal; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{self, DefLocation, Location, TerminatorKind}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; +use rustc_middle::{bug, span_bug}; pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( fx: &FunctionCx<'a, 'tcx, Bx>, diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index d4d172c000f3..be5458523d1c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -17,6 +17,7 @@ use rustc_middle::mir::{self, AssertKind, BasicBlock, SwitchTargets, UnwindTermi use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::{self, Instance, Ty}; +use rustc_middle::{bug, span_bug}; use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphization; use rustc_session::config::OptLevel; use rustc_span::{source_map::Spanned, sym, Span}; diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index c6260d359161..dba5fbefd8a7 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -5,6 +5,7 @@ use rustc_middle::mir; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::{self, Ty}; +use rustc_middle::{bug, span_bug}; use rustc_target::abi::Abi; use super::FunctionCx; diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index d0e2fc2de12f..50bf1ef61f3a 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -1,6 +1,7 @@ use crate::traits::*; use rustc_data_structures::fx::FxHashMap; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir; use rustc_middle::ty; diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index eb14a90412d5..2e008460798f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -9,6 +9,7 @@ use crate::traits::*; use crate::MemFlags; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_session::config::OptLevel; use rustc_span::{sym, Span}; use rustc_target::abi::{ diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index b98e90b5cde0..0064c16f5d9f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -8,6 +8,7 @@ use rustc_middle::mir::traversal; use rustc_middle::mir::UnwindTerminateReason; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_target::abi::call::{FnAbi, PassMode}; use std::iter; diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index e5fd59657a49..38f77f2e646f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -5,6 +5,7 @@ use crate::size_of_val; use crate::traits::*; use crate::MemFlags; +use rustc_middle::bug; use rustc_middle::mir::interpret::{alloc_range, Pointer, Scalar}; use rustc_middle::mir::{self, ConstValue}; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index b23d0894da67..870a105c61d6 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -5,6 +5,7 @@ use crate::common::IntPredicate; use crate::size_of_val; use crate::traits::*; +use rustc_middle::bug; use rustc_middle::mir; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 7823d4c249a8..4e7d251a2e92 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -8,11 +8,11 @@ use crate::traits::*; use crate::MemFlags; use rustc_hir as hir; -use rustc_middle::mir; -use rustc_middle::mir::{AggregateKind, Operand}; +use rustc_middle::mir::{self, AggregateKind, Operand}; use rustc_middle::ty::cast::{CastTy, IntTy}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_session::config::OptLevel; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{self, FIRST_VARIANT}; diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index 2188eeae4268..a0429022587c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs @@ -1,5 +1,5 @@ -use rustc_middle::mir; -use rustc_middle::mir::NonDivergingIntrinsic; +use rustc_middle::mir::{self, NonDivergingIntrinsic}; +use rustc_middle::span_bug; use rustc_session::config::OptLevel; use super::FunctionCx; diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs index df564f705bc7..40921c2932fa 100644 --- a/compiler/rustc_codegen_ssa/src/mono_item.rs +++ b/compiler/rustc_codegen_ssa/src/mono_item.rs @@ -5,6 +5,7 @@ use rustc_hir as hir; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::mono::MonoItem; use rustc_middle::mir::mono::{Linkage, Visibility}; +use rustc_middle::span_bug; use rustc_middle::ty; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; use rustc_middle::ty::Instance; diff --git a/compiler/rustc_codegen_ssa/src/size_of_val.rs b/compiler/rustc_codegen_ssa/src/size_of_val.rs index c250cc268232..032699f1fa15 100644 --- a/compiler/rustc_codegen_ssa/src/size_of_val.rs +++ b/compiler/rustc_codegen_ssa/src/size_of_val.rs @@ -5,6 +5,7 @@ use crate::common::IntPredicate; use crate::meth; use crate::traits::*; use rustc_hir::LangItem; +use rustc_middle::bug; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::{self, Ty}; use rustc_target::abi::WrappingRange; diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 241b0a15f787..bcddfe9fb9cb 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -8,6 +8,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LOCAL_CRATE; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::parse::feature_err; diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index 34d9e75036f8..ccb35629a829 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -3,6 +3,7 @@ use super::Backend; use super::HasCodegen; use crate::common::TypeKind; use crate::mir::place::PlaceRef; +use rustc_middle::bug; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::{self, Ty}; use rustc_target::abi::call::{ArgAbi, CastTarget, FnAbi, Reg}; diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index aa6f184a2d7d..8c66f239f8ee 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -46,6 +46,7 @@ use rustc_middle::dep_graph::{ }; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 0729986f32fd..79402c88de47 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -6,8 +6,6 @@ #![feature(rustdoc_internals)] #![allow(internal_features)] -#[macro_use] -extern crate rustc_middle; #[macro_use] extern crate tracing; diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index bf6ee044a0bd..3d7c0cfc30aa 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -110,6 +110,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_data_structures::{base_n, flock}; use rustc_errors::ErrorGuaranteed; use rustc_fs_util::{link_or_copy, try_canonicalize, LinkOrCopy}; +use rustc_middle::bug; use rustc_session::config::CrateType; use rustc_session::output::{collect_crate_types, find_crate_name}; use rustc_session::{Session, StableCrateId}; diff --git a/compiler/rustc_lint/src/array_into_iter.rs b/compiler/rustc_lint/src/array_into_iter.rs index ce5f3052e2a5..8f4bae339573 100644 --- a/compiler/rustc_lint/src/array_into_iter.rs +++ b/compiler/rustc_lint/src/array_into_iter.rs @@ -3,6 +3,7 @@ use crate::{ LateContext, LateLintPass, LintContext, }; use rustc_hir as hir; +use rustc_middle::bug; use rustc_middle::ty; use rustc_middle::ty::adjustment::{Adjust, Adjustment}; use rustc_session::lint::FutureIncompatibilityReason; diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 9b7e740d883e..ba316e5eeb04 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -51,6 +51,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; use rustc_hir::intravisit::FnKind as HirFnKind; use rustc_hir::{Body, FnDecl, GenericParamKind, Node, PatKind, PredicateOrigin}; +use rustc_middle::bug; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::print::with_no_trimmed_paths; diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index d1dcfc524b55..64197a7ec692 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -27,6 +27,7 @@ use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; +use rustc_middle::bug; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::print::{with_no_trimmed_paths, PrintError}; diff --git a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs index 0472525d49a4..e9a6276192e5 100644 --- a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs +++ b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs @@ -1,4 +1,5 @@ use rustc_errors::{Applicability, Diag}; +use rustc_middle::bug; use rustc_session::{config::ExpectedValues, Session}; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::{sym, Span, Symbol}; diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 5bb2942ad4b7..12b3d1d2f9e4 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -22,6 +22,7 @@ use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::HirId; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::lint::{ lint_level, reveal_actual_level, LevelAndSource, LintExpectation, LintLevelSource, diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 901c9b19ba35..a78b410f500c 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -39,8 +39,6 @@ #![feature(rustc_attrs)] #![allow(internal_features)] -#[macro_use] -extern crate rustc_middle; #[macro_use] extern crate tracing; diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index 6527e10c580f..a6057afcbd6b 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -4,6 +4,7 @@ use rustc_ast as ast; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::bug; use rustc_middle::lint::in_external_macro; use rustc_middle::ty; use rustc_parse_format::{ParseMode, Parser, Piece}; diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index ff4e3141f1f1..13b6054586cd 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -17,6 +17,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::DiagMessage; use rustc_hir as hir; use rustc_hir::{is_range_literal, Expr, ExprKind, Node}; +use rustc_middle::bug; use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton}; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{ diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index d63db6ea8edd..bfc01dc4da4b 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -2,6 +2,7 @@ use rustc_hir::lang_items::LangItem; use rustc_index::Idx; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::*; +use rustc_middle::span_bug; use rustc_middle::traits::Reveal; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::GenericArgsRef; diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs index 44a7dcc82775..ea9cf6565e7c 100644 --- a/compiler/rustc_mir_dataflow/src/framework/engine.rs +++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs @@ -13,6 +13,7 @@ use rustc_data_structures::work_queue::WorkQueue; use rustc_graphviz as dot; use rustc_hir::def_id::DefId; use rustc_index::{Idx, IndexVec}; +use rustc_middle::bug; use rustc_middle::mir::{self, traversal, BasicBlock}; use rustc_middle::mir::{create_dump_file, dump_enabled}; use rustc_middle::ty::print::with_no_trimmed_paths; diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index 720515f262db..180168c73168 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -1,5 +1,6 @@ use rustc_index::bit_set::{BitSet, ChunkedBitSet}; use rustc_index::Idx; +use rustc_middle::bug; use rustc_middle::mir::{self, Body, CallReturnPlaces, Location, TerminatorEdges}; use rustc_middle::ty::{self, TyCtxt}; diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index c5adb81b614c..5e96a73f6c53 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -6,8 +6,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; use rustc_middle::ty; diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index d7477309400b..6ae7df79d309 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -2,6 +2,7 @@ use rustc_index::IndexVec; use rustc_middle::mir::tcx::{PlaceTy, RvalueInitializationState}; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use smallvec::{smallvec, SmallVec}; use std::mem; diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 0e85f859ab2c..807bef074117 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -40,6 +40,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_index::bit_set::BitSet; use rustc_index::{IndexSlice, IndexVec}; +use rustc_middle::bug; use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt}; diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index a8fa6fe002db..dd1065590b30 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -228,6 +228,7 @@ use rustc_middle::ty::{ TypeVisitableExt, VtblEntry, }; use rustc_middle::ty::{GenericArgKind, GenericArgs}; +use rustc_middle::{bug, span_bug}; use rustc_session::config::EntryFnType; use rustc_session::Limit; use rustc_span::source_map::{dummy_spanned, respan, Spanned}; diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 2a91d69529a8..cbab20061861 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -4,10 +4,9 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; use rustc_hir::lang_items::LangItem; +use rustc_middle::bug; use rustc_middle::query::{Providers, TyCtxtAt}; use rustc_middle::traits; use rustc_middle::ty::adjustment::CustomCoerceUnsized; diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 23e07890bb6c..8f7b4c6472c9 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -103,6 +103,7 @@ use rustc_data_structures::sync; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdSet, LOCAL_CRATE}; use rustc_hir::definitions::DefPathDataName; +use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel}; use rustc_middle::mir::mono::{ diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs index 986ef69ad884..0c3dd649997e 100644 --- a/compiler/rustc_passes/src/abi_test.rs +++ b/compiler/rustc_passes/src/abi_test.rs @@ -1,6 +1,7 @@ use rustc_ast::Attribute; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; +use rustc_middle::span_bug; use rustc_middle::ty::layout::{FnAbiError, LayoutError}; use rustc_middle::ty::{self, GenericArgs, Instance, Ty, TyCtxt}; use rustc_span::source_map::Spanned; diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index a2388b3bd522..c403e9196fab 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -19,6 +19,7 @@ use rustc_hir::{ }; use rustc_hir::{MethodKind, Target, Unsafety}; use rustc_macros::LintDiagnostic; +use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault; use rustc_middle::query::Providers; diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index 4a1a20490835..eb29a65cb293 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -13,6 +13,7 @@ use rustc_hir::def_id::{LocalDefId, LocalModDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::hir::nested_filter; use rustc_middle::query::Providers; +use rustc_middle::span_bug; use rustc_middle::ty::TyCtxt; use rustc_session::parse::feature_err; use rustc_span::{sym, Span, Symbol}; diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 51f288b3c959..933412f677ce 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -16,6 +16,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::privacy::Level; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_session::lint::builtin::DEAD_CODE; use rustc_span::symbol::{sym, Symbol}; diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index 8d223c23363b..82d43f078ee2 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -1,6 +1,7 @@ use rustc_ast::Attribute; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; +use rustc_middle::span_bug; use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt}; use rustc_span::source_map::Spanned; diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index bce29e2af09b..d3608759eec7 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -12,8 +12,6 @@ #![feature(map_try_insert)] #![feature(try_blocks)] -#[macro_use] -extern crate rustc_middle; #[macro_use] extern crate tracing; diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index c7729302783f..b50cb158b1fe 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -94,6 +94,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Expr, HirId, HirIdMap, HirIdSet}; use rustc_index::IndexVec; use rustc_middle::query::Providers; +use rustc_middle::span_bug; use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt}; use rustc_session::lint; use rustc_span::symbol::{kw, sym, Symbol}; diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index e10a22cdf31b..4b5c4dfe991b 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -6,6 +6,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Destination, Node}; use rustc_middle::hir::nested_filter; use rustc_middle::query::Providers; +use rustc_middle::span_bug; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::hygiene::DesugaringKind; diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 869cbebbc0de..d5e1a70fd45c 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -17,6 +17,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::Node; +use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::middle::privacy::{self, Level}; use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc}; diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index 6e8843d90497..7ec5ddbd91e1 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -16,9 +16,6 @@ pub mod usefulness; #[macro_use] extern crate tracing; -#[cfg(feature = "rustc")] -#[macro_use] -extern crate rustc_middle; #[cfg(feature = "rustc")] rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 548a7b430055..ff68dd81beaf 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -11,6 +11,7 @@ use rustc_middle::mir::{self, Const}; use rustc_middle::thir::{self, FieldPat, Pat, PatKind, PatRange, PatRangeBoundary}; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{self, FieldDef, OpaqueTypeKey, Ty, TyCtxt, TypeVisitableExt, VariantDef}; +use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP}; use rustc_target::abi::{FieldIdx, Integer, VariantIdx, FIRST_VARIANT}; diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index f1c3512315ff..4a4fde78d2de 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -1,6 +1,7 @@ use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; use rustc_hir::def_id::CrateNum; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; +use rustc_middle::bug; use rustc_middle::ty::print::{PrettyPrinter, Print, PrintError, Printer}; use rustc_middle::ty::{self, Instance, ReifyReason, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{GenericArg, GenericArgKind}; diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index b95094787027..d526436f8237 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -93,9 +93,6 @@ #![feature(let_chains)] #![allow(internal_features)] -#[macro_use] -extern crate rustc_middle; - #[macro_use] extern crate tracing; diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 58b67c77a615..fc2c3dcb2d95 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -5,6 +5,7 @@ use rustc_hir as hir; use rustc_hir::def::CtorKind; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; +use rustc_middle::bug; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::print::{Print, PrintError, Printer}; use rustc_middle::ty::{ diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index b2b5c6cd9096..49e101b51e63 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -5,6 +5,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{FulfillmentErrorCode, TraitEngineExt as _}; +use rustc_middle::bug; use rustc_middle::traits::CodegenObligationError; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index f40c3614e1c0..4cee266adf96 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::DefId; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::traits::query::{DropckConstraint, DropckOutlivesResult}; use rustc_middle::ty::GenericArgs; diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs index e73bbf6048ec..5fdbfadf1d03 100644 --- a/compiler/rustc_traits/src/lib.rs +++ b/compiler/rustc_traits/src/lib.rs @@ -4,8 +4,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; mod codegen; mod dropck_outlives; From cbdc36aa091d4d99a4848155a74a770d3793219b Mon Sep 17 00:00:00 2001 From: J-ZhengLi Date: Mon, 29 Apr 2024 13:38:45 +0800 Subject: [PATCH 147/279] skip warning when generic evolved; suggest explicit type when its inferred in closure --- clippy_lints/src/manual_is_ascii_check.rs | 88 +++++++++++++++-------- tests/ui/manual_is_ascii_check.fixed | 27 +++++++ tests/ui/manual_is_ascii_check.rs | 27 +++++++ tests/ui/manual_is_ascii_check.stderr | 42 ++++++++++- 4 files changed, 152 insertions(+), 32 deletions(-) diff --git a/clippy_lints/src/manual_is_ascii_check.rs b/clippy_lints/src/manual_is_ascii_check.rs index ed7eabd9b994..6f6ba1852a68 100644 --- a/clippy_lints/src/manual_is_ascii_check.rs +++ b/clippy_lints/src/manual_is_ascii_check.rs @@ -1,13 +1,14 @@ use clippy_config::msrvs::{self, Msrv}; -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::matching_root_macro_call; use clippy_utils::sugg::Sugg; -use clippy_utils::{higher, in_constant}; +use clippy_utils::{higher, in_constant, path_to_local, peel_ref_operators}; use rustc_ast::ast::RangeLimits; use rustc_ast::LitKind::{Byte, Char}; use rustc_errors::Applicability; -use rustc_hir::{BorrowKind, Expr, ExprKind, PatKind, RangeEnd}; +use rustc_hir::{Expr, ExprKind, Node, Param, PatKind, RangeEnd}; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty; use rustc_session::impl_lint_pass; use rustc_span::{sym, Span}; @@ -99,7 +100,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck { if let Some(macro_call) = matching_root_macro_call(cx, expr.span, sym::matches_macro) { if let ExprKind::Match(recv, [arm, ..], _) = expr.kind { let range = check_pat(&arm.pat.kind); - check_is_ascii(cx, macro_call.span, recv, &range); + check_is_ascii(cx, macro_call.span, recv, &range, None); } } else if let ExprKind::MethodCall(path, receiver, [arg], ..) = expr.kind && path.ident.name == sym!(contains) @@ -108,42 +109,67 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck { end: Some(end), limits: RangeLimits::Closed, }) = higher::Range::hir(receiver) + && !matches!(cx.typeck_results().expr_ty(arg).peel_refs().kind(), ty::Param(_)) { + let arg = peel_ref_operators(cx, arg); + let ty_sugg = get_ty_sugg(cx, arg, start); let range = check_range(start, end); - if let ExprKind::AddrOf(BorrowKind::Ref, _, e) = arg.kind { - check_is_ascii(cx, expr.span, e, &range); - } else { - check_is_ascii(cx, expr.span, arg, &range); - } + check_is_ascii(cx, expr.span, arg, &range, ty_sugg); } } extract_msrv_attr!(LateContext); } -fn check_is_ascii(cx: &LateContext<'_>, span: Span, recv: &Expr<'_>, range: &CharRange) { - if let Some(sugg) = match range { - CharRange::UpperChar => Some("is_ascii_uppercase"), - CharRange::LowerChar => Some("is_ascii_lowercase"), - CharRange::FullChar => Some("is_ascii_alphabetic"), - CharRange::Digit => Some("is_ascii_digit"), - CharRange::HexDigit => Some("is_ascii_hexdigit"), - CharRange::Otherwise | CharRange::LowerHexLetter | CharRange::UpperHexLetter => None, - } { - let default_snip = ".."; - let mut app = Applicability::MachineApplicable; - let recv = Sugg::hir_with_context(cx, recv, span.ctxt(), default_snip, &mut app).maybe_par(); - - span_lint_and_sugg( - cx, - MANUAL_IS_ASCII_CHECK, - span, - "manual check for common ascii range", - "try", - format!("{recv}.{sugg}()"), - app, - ); +fn get_ty_sugg(cx: &LateContext<'_>, arg: &Expr<'_>, bound_expr: &Expr<'_>) -> Option<(Span, &'static str)> { + if let ExprKind::Lit(lit) = bound_expr.kind + && let local_hid = path_to_local(arg)? + && let Node::Param(Param { ty_span, span, .. }) = cx.tcx.parent_hir_node(local_hid) + // `ty_span` and `span` are the same for inferred type, thus a type suggestion must be given + && ty_span == span + { + let ty_str = match lit.node { + Char(_) => "char", + Byte(_) => "u8", + _ => return None, + }; + return Some((*ty_span, ty_str)); } + None +} + +fn check_is_ascii( + cx: &LateContext<'_>, + span: Span, + recv: &Expr<'_>, + range: &CharRange, + ty_sugg: Option<(Span, &'_ str)>, +) { + let sugg = match range { + CharRange::UpperChar => "is_ascii_uppercase", + CharRange::LowerChar => "is_ascii_lowercase", + CharRange::FullChar => "is_ascii_alphabetic", + CharRange::Digit => "is_ascii_digit", + CharRange::HexDigit => "is_ascii_hexdigit", + CharRange::Otherwise | CharRange::LowerHexLetter | CharRange::UpperHexLetter => return, + }; + let default_snip = ".."; + let mut app = Applicability::MachineApplicable; + let recv = Sugg::hir_with_context(cx, recv, span.ctxt(), default_snip, &mut app).maybe_par(); + let mut suggestion = vec![(span, format!("{recv}.{sugg}()"))]; + if let Some((ty_span, ty_str)) = ty_sugg { + suggestion.push((ty_span, format!("{recv}: {ty_str}"))); + } + + span_lint_and_then( + cx, + MANUAL_IS_ASCII_CHECK, + span, + "manual check for common ascii range", + |diag| { + diag.multipart_suggestion("try", suggestion, app); + }, + ); } fn check_pat(pat_kind: &PatKind<'_>) -> CharRange { diff --git a/tests/ui/manual_is_ascii_check.fixed b/tests/ui/manual_is_ascii_check.fixed index 9c4bd335ad8b..a72caa3a37ee 100644 --- a/tests/ui/manual_is_ascii_check.fixed +++ b/tests/ui/manual_is_ascii_check.fixed @@ -55,3 +55,30 @@ fn msrv_1_47() { const FOO: bool = 'x'.is_ascii_digit(); const BAR: bool = 'x'.is_ascii_hexdigit(); } + +#[allow(clippy::deref_addrof, clippy::needless_borrow)] +fn with_refs() { + let cool_letter = &&'g'; + cool_letter.is_ascii_digit(); + cool_letter.is_ascii_lowercase(); +} + +fn generics() { + fn a(u: &U) -> bool + where + char: PartialOrd, + U: PartialOrd + ?Sized, + { + ('A'..='Z').contains(u) + } + + fn take_while(cond: F) + where + Item: Sized, + F: Fn(Item) -> bool, + { + } + take_while(|c: char| c.is_ascii_uppercase()); + take_while(|c: u8| c.is_ascii_uppercase()); + take_while(|c: char| c.is_ascii_uppercase()); +} diff --git a/tests/ui/manual_is_ascii_check.rs b/tests/ui/manual_is_ascii_check.rs index 785943cd24d2..bb6e2a317da1 100644 --- a/tests/ui/manual_is_ascii_check.rs +++ b/tests/ui/manual_is_ascii_check.rs @@ -55,3 +55,30 @@ fn msrv_1_47() { const FOO: bool = matches!('x', '0'..='9'); const BAR: bool = matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F'); } + +#[allow(clippy::deref_addrof, clippy::needless_borrow)] +fn with_refs() { + let cool_letter = &&'g'; + ('0'..='9').contains(&&cool_letter); + ('a'..='z').contains(*cool_letter); +} + +fn generics() { + fn a(u: &U) -> bool + where + char: PartialOrd, + U: PartialOrd + ?Sized, + { + ('A'..='Z').contains(u) + } + + fn take_while(cond: F) + where + Item: Sized, + F: Fn(Item) -> bool, + { + } + take_while(|c| ('A'..='Z').contains(&c)); + take_while(|c| (b'A'..=b'Z').contains(&c)); + take_while(|c: char| ('A'..='Z').contains(&c)); +} diff --git a/tests/ui/manual_is_ascii_check.stderr b/tests/ui/manual_is_ascii_check.stderr index 3632077ec808..a93ccace28a6 100644 --- a/tests/ui/manual_is_ascii_check.stderr +++ b/tests/ui/manual_is_ascii_check.stderr @@ -133,5 +133,45 @@ error: manual check for common ascii range LL | const BAR: bool = matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F'); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_hexdigit()` -error: aborting due to 22 previous errors +error: manual check for common ascii range + --> tests/ui/manual_is_ascii_check.rs:62:5 + | +LL | ('0'..='9').contains(&&cool_letter); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cool_letter.is_ascii_digit()` + +error: manual check for common ascii range + --> tests/ui/manual_is_ascii_check.rs:63:5 + | +LL | ('a'..='z').contains(*cool_letter); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cool_letter.is_ascii_lowercase()` + +error: manual check for common ascii range + --> tests/ui/manual_is_ascii_check.rs:81:20 + | +LL | take_while(|c| ('A'..='Z').contains(&c)); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL | take_while(|c: char| c.is_ascii_uppercase()); + | ~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ + +error: manual check for common ascii range + --> tests/ui/manual_is_ascii_check.rs:82:20 + | +LL | take_while(|c| (b'A'..=b'Z').contains(&c)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL | take_while(|c: u8| c.is_ascii_uppercase()); + | ~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ + +error: manual check for common ascii range + --> tests/ui/manual_is_ascii_check.rs:83:26 + | +LL | take_while(|c: char| ('A'..='Z').contains(&c)); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `c.is_ascii_uppercase()` + +error: aborting due to 27 previous errors From f3e05d1609e129c3169015bc108af1c7e9262c68 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 29 Apr 2024 15:35:31 +1000 Subject: [PATCH 148/279] Remove `extern crate rustc_data_structures` from `rustc_query_system`. --- .../src/dep_graph/dep_node.rs | 25 +++++++++++-------- .../rustc_query_system/src/dep_graph/graph.rs | 10 ++++---- compiler/rustc_query_system/src/lib.rs | 2 -- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs index 9c196093f231..5f1a03502a70 100644 --- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs +++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs @@ -76,8 +76,6 @@ impl DepKind { } } -static_assert_size!(DepKind, 2); - pub fn default_dep_kind_debug(kind: DepKind, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("DepKind").field("variant", &kind.variant).finish() } @@ -97,15 +95,6 @@ pub struct DepNode { pub hash: PackedFingerprint, } -// We keep a lot of `DepNode`s in memory during compilation. It's not -// required that their size stay the same, but we don't want to change -// it inadvertently. This assert just ensures we're aware of any change. -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -static_assert_size!(DepNode, 18); - -#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] -static_assert_size!(DepNode, 24); - impl DepNode { /// Creates a new, parameterless DepNode. This method will assert /// that the DepNode corresponding to the given DepKind actually @@ -316,3 +305,17 @@ unsafe impl StableOrd for WorkProductId { // Fingerprint can use unstable (just a tuple of `u64`s), so WorkProductId can as well const CAN_USE_UNSTABLE_SORT: bool = true; } + +// Some types are used a lot. Make sure they don't unintentionally get bigger. +#[cfg(target_pointer_width = "64")] +mod size_asserts { + use super::*; + use rustc_data_structures::static_assert_size; + // tidy-alphabetical-start + static_assert_size!(DepKind, 2); + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + static_assert_size!(DepNode, 18); + #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] + static_assert_size!(DepNode, 24); + // tidy-alphabetical-end +} diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 3e4e2e919fba..07543b79f975 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -41,6 +41,11 @@ rustc_index::newtype_index! { pub struct DepNodeIndex {} } +// We store a large collection of these in `prev_index_to_index` during +// non-full incremental builds, and want to ensure that the element size +// doesn't inadvertently increase. +rustc_data_structures::static_assert_size!(Option, 4); + impl DepNodeIndex { const SINGLETON_DEPENDENCYLESS_ANON_NODE: DepNodeIndex = DepNodeIndex::ZERO; pub const FOREVER_RED_NODE: DepNodeIndex = DepNodeIndex::from_u32(1); @@ -1107,11 +1112,6 @@ impl CurrentDepGraph { Err(_) => None, }; - // We store a large collection of these in `prev_index_to_index` during - // non-full incremental builds, and want to ensure that the element size - // doesn't inadvertently increase. - static_assert_size!(Option, 4); - let new_node_count_estimate = 102 * prev_graph_node_count / 100 + 200; CurrentDepGraph { diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index e1743b147d4d..6ed0b1b1d9df 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -7,8 +7,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_data_structures; pub mod cache; pub mod dep_graph; From fa6db4c4281ec814798ff217a485b504a49a6411 Mon Sep 17 00:00:00 2001 From: ivmarkov Date: Mon, 29 Apr 2024 06:17:02 +0000 Subject: [PATCH 149/279] Fix ESP IDF build broken by #124210 --- library/std/src/sys/pal/unix/fs.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index abd32b819e03..5987996a3f16 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -893,6 +893,7 @@ impl Drop for Dir { target_os = "nto", target_os = "vita", target_os = "hurd", + target_os = "espidf", )))] { let fd = unsafe { libc::dirfd(self.0) }; From a25a11ad73dba9d75c576874d7bb1c03dd69fb26 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 29 Apr 2024 16:36:55 +1000 Subject: [PATCH 150/279] coverage: Avoid hard-coded values when visiting logical ops Instead of separately hard-coding the operation being visited, we can get it from the match arm pattern by using an as-pattern. --- compiler/rustc_mir_build/src/build/matches/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index d36c51f44727..133cd36e71a5 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -73,14 +73,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let expr_span = expr.span; match expr.kind { - ExprKind::LogicalOp { op: LogicalOp::And, lhs, rhs } => { - this.visit_coverage_branch_operation(LogicalOp::And, expr_span); + ExprKind::LogicalOp { op: op @ LogicalOp::And, lhs, rhs } => { + this.visit_coverage_branch_operation(op, expr_span); let lhs_then_block = unpack!(this.then_else_break_inner(block, lhs, args)); let rhs_then_block = unpack!(this.then_else_break_inner(lhs_then_block, rhs, args)); rhs_then_block.unit() } - ExprKind::LogicalOp { op: LogicalOp::Or, lhs, rhs } => { - this.visit_coverage_branch_operation(LogicalOp::Or, expr_span); + ExprKind::LogicalOp { op: op @ LogicalOp::Or, lhs, rhs } => { + this.visit_coverage_branch_operation(op, expr_span); let local_scope = this.local_scope(); let (lhs_success_block, failure_block) = this.in_if_then_scope(local_scope, expr_span, |this| { From feeb1842cb83134e934c940b01cfd1a9816861d2 Mon Sep 17 00:00:00 2001 From: Petr Sumbera Date: Mon, 29 Apr 2024 08:58:59 +0200 Subject: [PATCH 151/279] Normalize bootstrap_out path, r=clubby789 --- src/bootstrap/src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 85211aabb74c..aaf37d33c235 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -370,11 +370,16 @@ impl Build { .expect("failed to read src/version"); let version = version.trim(); - let bootstrap_out = std::env::current_exe() + let mut bootstrap_out = std::env::current_exe() .expect("could not determine path to running process") .parent() .unwrap() .to_path_buf(); + // Since bootstrap is hardlink to deps/bootstrap-*, Solaris can sometimes give + // path with deps/ which is bad and needs to be avoided. + if bootstrap_out.ends_with("deps") { + bootstrap_out.pop(); + } if !bootstrap_out.join(exe("rustc", config.build)).exists() && !cfg!(test) { // this restriction can be lifted whenever https://github.com/rust-lang/rfcs/pull/3028 is implemented panic!( From 3c2f48ede9ce927950d74832722e6f716a69d974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dorian=20P=C3=A9ron?= Date: Mon, 8 Apr 2024 14:23:50 +0000 Subject: [PATCH 152/279] mcdc-coverage: Add possibility for codegen llvm to handle several condition bitmaps --- compiler/rustc_codegen_llvm/src/builder.rs | 31 ++++++++++++------- .../src/coverageinfo/mod.rs | 25 ++++++++++----- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 4c2bdb2f5ec2..bd09797a677b 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -27,6 +27,7 @@ use rustc_target::abi::{self, call::FnAbi, Align, Size, WrappingRange}; use rustc_target::spec::{HasTargetSpec, SanitizerSet, Target}; use smallvec::SmallVec; use std::borrow::Cow; +use std::ffi::CString; use std::iter; use std::ops::Deref; use std::ptr; @@ -1708,7 +1709,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { fn_name: &'ll Value, hash: &'ll Value, bitmap_bytes: &'ll Value, - ) -> &'ll Value { + max_decision_depth: u32, + ) -> Vec<&'ll Value> { debug!("mcdc_parameters() with args ({:?}, {:?}, {:?})", fn_name, hash, bitmap_bytes); assert!(llvm_util::get_version() >= (18, 0, 0), "MCDC intrinsics require LLVM 18 or later"); @@ -1721,6 +1723,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { let args = &[fn_name, hash, bitmap_bytes]; let args = self.check_call("call", llty, llfn, args); + let mut cond_bitmaps = vec![]; + unsafe { let _ = llvm::LLVMRustBuildCall( self.llbuilder, @@ -1732,17 +1736,22 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { 0 as c_uint, ); // Create condition bitmap named `mcdc.addr`. - let mut bx = Builder::with_cx(self.cx); - bx.position_at_start(llvm::LLVMGetFirstBasicBlock(self.llfn())); - let cond_bitmap = { - let alloca = - llvm::LLVMBuildAlloca(bx.llbuilder, bx.cx.type_i32(), c"mcdc.addr".as_ptr()); - llvm::LLVMSetAlignment(alloca, 4); - alloca - }; - bx.store(self.const_i32(0), cond_bitmap, self.tcx().data_layout.i32_align.abi); - cond_bitmap + for i in 0..=max_decision_depth { + let mut bx = Builder::with_cx(self.cx); + bx.position_at_start(llvm::LLVMGetFirstBasicBlock(self.llfn())); + + let name = CString::new(format!("mcdc.addr.{i}")).unwrap(); + let cond_bitmap = { + let alloca = + llvm::LLVMBuildAlloca(bx.llbuilder, bx.cx.type_i32(), name.as_ptr()); + llvm::LLVMSetAlignment(alloca, 4); + alloca + }; + bx.store(self.const_i32(0), cond_bitmap, self.tcx().data_layout.i32_align.abi); + cond_bitmaps.push(cond_bitmap); + } } + cond_bitmaps } pub(crate) fn mcdc_tvbitmap_update( diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index 085ce15d81fe..03fc2ae425b0 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -30,7 +30,7 @@ pub struct CrateCoverageContext<'ll, 'tcx> { pub(crate) function_coverage_map: RefCell, FunctionCoverageCollector<'tcx>>>, pub(crate) pgo_func_name_var_map: RefCell, &'ll llvm::Value>>, - pub(crate) mcdc_condition_bitmap_map: RefCell, &'ll llvm::Value>>, + pub(crate) mcdc_condition_bitmap_map: RefCell, Vec<&'ll llvm::Value>>>, } impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> { @@ -49,9 +49,20 @@ impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> { } /// LLVM use a temp value to record evaluated mcdc test vector of each decision, which is called condition bitmap. - /// This value is named `mcdc.addr` (same as clang) and is a 32-bit integer. - fn try_get_mcdc_condition_bitmap(&self, instance: &Instance<'tcx>) -> Option<&'ll llvm::Value> { - self.mcdc_condition_bitmap_map.borrow().get(instance).copied() + /// In order to handle nested decisions, several condition bitmaps can be + /// allocated for a function body. + /// These values are named `mcdc.addr.{i}` and are a 32-bit integers. + /// They respectively hold the condition bitmaps for decisions with a depth of `i`. + fn try_get_mcdc_condition_bitmap( + &self, + instance: &Instance<'tcx>, + decision_depth: u16, + ) -> Option<&'ll llvm::Value> { + self.mcdc_condition_bitmap_map + .borrow() + .get(instance) + .and_then(|bitmap_map| bitmap_map.get(decision_depth as usize)) + .copied() // Dereference Option<&&Value> to Option<&Value> } } @@ -151,7 +162,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { "ConditionId of evaluated conditions should never be zero" ); let cond_bitmap = coverage_context - .try_get_mcdc_condition_bitmap(&instance) + .try_get_mcdc_condition_bitmap(&instance, 0) .expect("mcdc cond bitmap should have been allocated for updating"); let cond_loc = bx.const_i32(id.as_u32() as i32 - 1); let bool_value = bx.const_bool(value); @@ -162,7 +173,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { CoverageKind::TestVectorBitmapUpdate { bitmap_idx } => { drop(coverage_map); let cond_bitmap = coverage_context - .try_get_mcdc_condition_bitmap(&instance) + .try_get_mcdc_condition_bitmap(&instance, 0) .expect("mcdc cond bitmap should have been allocated for merging into the global bitmap"); let bitmap_bytes = bx.tcx().coverage_ids_info(instance.def).mcdc_bitmap_bytes; assert!(bitmap_idx < bitmap_bytes, "bitmap index of the decision out of range"); @@ -195,7 +206,7 @@ fn ensure_mcdc_parameters<'ll, 'tcx>( let fn_name = bx.get_pgo_func_name_var(instance); let hash = bx.const_u64(function_coverage_info.function_source_hash); let bitmap_bytes = bx.const_u32(function_coverage_info.mcdc_bitmap_bytes); - let cond_bitmap = bx.mcdc_parameters(fn_name, hash, bitmap_bytes); + let cond_bitmap = bx.mcdc_parameters(fn_name, hash, bitmap_bytes, 1_u32); bx.coverage_context() .expect("already checked above") .mcdc_condition_bitmap_map From e6f0e03e5fec367d1a71a696238b210531ea9d51 Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Mon, 29 Apr 2024 09:42:50 +0100 Subject: [PATCH 153/279] Adding new arm target docs to SUMMARY.md --- src/doc/rustc/src/SUMMARY.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 31096b6df92b..9dd68555bbe1 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -55,6 +55,13 @@ - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md) - [riscv32*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md) - [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md) + - [thumbv6m-none-eabi](./platform-support/thumbv6m-none-eabi.md) + - [thumbv7m-none-eabi](./platform-support/thumbv7m-none-eabi.md) + - [thumbv7em-none-eabi](./platform-support/thumbv7em-none-eabi.md) + - [thumbv7em-none-eabihf](./platform-support/thumbv7em-none-eabihf.md) + - [thumbv8m.base-none-eabi](./platform-support/thumbv8m.base-none-eabi.md) + - [thumbv8m.main-none-eabi](./platform-support/thumbv8m.main-none-eabi.md) + - [thumbv8m.main-none-eabihf](./platform-support/thumbv8m.main-none-eabihf.md) - [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md) - [\*-nto-qnx-\*](platform-support/nto-qnx.md) - [*-unikraft-linux-musl](platform-support/unikraft-linux-musl.md) From 7418aa1a075f823816eb0f9020c64204ceb384e0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 29 Apr 2024 14:59:24 +1000 Subject: [PATCH 154/279] Remove `extern crate rustc_data_structures` from numerous crates. --- compiler/rustc_hir/src/hir.rs | 1 + compiler/rustc_hir/src/lang_items.rs | 2 +- compiler/rustc_hir/src/lib.rs | 3 --- compiler/rustc_infer/src/infer/mod.rs | 2 +- compiler/rustc_infer/src/lib.rs | 3 --- compiler/rustc_infer/src/traits/mod.rs | 2 +- compiler/rustc_middle/src/lib.rs | 2 -- compiler/rustc_middle/src/middle/region.rs | 2 +- compiler/rustc_middle/src/mir/consts.rs | 2 +- compiler/rustc_middle/src/mir/interpret/error.rs | 2 +- compiler/rustc_middle/src/mir/interpret/pointer.rs | 1 + compiler/rustc_middle/src/mir/interpret/value.rs | 2 +- compiler/rustc_middle/src/mir/syntax.rs | 1 + compiler/rustc_middle/src/mir/tcx.rs | 2 +- compiler/rustc_middle/src/tests.rs | 2 -- compiler/rustc_middle/src/thir.rs | 1 + compiler/rustc_middle/src/traits/mod.rs | 2 +- compiler/rustc_middle/src/ty/consts.rs | 4 ++-- compiler/rustc_middle/src/ty/consts/kind.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_trait_selection/src/lib.rs | 3 --- compiler/rustc_trait_selection/src/traits/fulfill.rs | 2 +- 22 files changed, 18 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 5850fbe5c250..05431cf3780e 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3863,6 +3863,7 @@ impl<'hir> Node<'hir> { #[cfg(target_pointer_width = "64")] mod size_asserts { use super::*; + use rustc_data_structures::static_assert_size; // tidy-alphabetical-start static_assert_size!(Block<'_>, 48); static_assert_size!(Body<'_>, 24); diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 969ec0dc534e..e870a04127ad 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -56,7 +56,7 @@ macro_rules! language_item_table { $( $(#[$attr:meta])* $variant:ident, $module:ident :: $name:ident, $method:ident, $target:expr, $generics:expr; )* ) => { - enum_from_u32! { + rustc_data_structures::enum_from_u32! { /// A representation of all the valid lang items in Rust. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)] pub enum LangItem { diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index f3eea54a7add..da3c3b41d1cd 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -13,9 +13,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_data_structures; - extern crate self as rustc_hir; mod arena; diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index e04bb2d84d25..bb53aec0b4d1 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -479,7 +479,7 @@ pub enum SubregionOrigin<'tcx> { // `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_pointer_width = "64")] -static_assert_size!(SubregionOrigin<'_>, 32); +rustc_data_structures::static_assert_size!(SubregionOrigin<'_>, 32); impl<'tcx> SubregionOrigin<'tcx> { pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> { diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index b857d439cb79..9370e84a19a6 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -30,9 +30,6 @@ #![feature(yeet_expr)] #![recursion_limit = "512"] // For rustdoc -#[cfg(target_pointer_width = "64")] -#[macro_use] -extern crate rustc_data_structures; #[macro_use] extern crate tracing; #[macro_use] diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 7b4e085293c4..e3611ab28e53 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -113,7 +113,7 @@ impl<'tcx> PolyTraitObligation<'tcx> { // `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_pointer_width = "64")] -static_assert_size!(PredicateObligation<'_>, 48); +rustc_data_structures::static_assert_size!(PredicateObligation<'_>, 48); pub type PredicateObligations<'tcx> = Vec>; diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 9afc68ef2306..da90ae5420fd 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -68,8 +68,6 @@ #[macro_use] extern crate bitflags; #[macro_use] -extern crate rustc_data_structures; -#[macro_use] extern crate tracing; #[macro_use] extern crate smallvec; diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index da32dbc3065a..de07ba9700ac 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -153,7 +153,7 @@ rustc_index::newtype_index! { } // compilation error if size of `ScopeData` is not the same as a `u32` -static_assert_size!(ScopeData, 4); +rustc_data_structures::static_assert_size!(ScopeData, 4); impl Scope { /// Returns an item-local ID associated with this scope. diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index dfb645e6a228..d025dc360a24 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -72,7 +72,7 @@ pub enum ConstValue<'tcx> { } #[cfg(target_pointer_width = "64")] -static_assert_size!(ConstValue<'_>, 24); +rustc_data_structures::static_assert_size!(ConstValue<'_>, 24); impl<'tcx> ConstValue<'tcx> { #[inline] diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 93044a1c53ed..383241465c3d 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -89,7 +89,7 @@ pub type EvalToConstValueResult<'tcx> = Result, ErrorHandled>; pub type EvalToValTreeResult<'tcx> = Result>, ErrorHandled>; #[cfg(target_pointer_width = "64")] -static_assert_size!(InterpErrorInfo<'_>, 8); +rustc_data_structures::static_assert_size!(InterpErrorInfo<'_>, 8); /// Packages the kind of error we got from the const code interpreter /// up with a Rust-level backtrace of where the error occurred. diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs index ff57053fa051..a0acacc844fd 100644 --- a/compiler/rustc_middle/src/mir/interpret/pointer.rs +++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs @@ -1,5 +1,6 @@ use super::{AllocId, InterpResult}; +use rustc_data_structures::static_assert_size; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_target::abi::{HasDataLayout, Size}; diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index 352409bcef98..c5c87c506b77 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -38,7 +38,7 @@ pub enum Scalar { } #[cfg(target_pointer_width = "64")] -static_assert_size!(Scalar, 24); +rustc_data_structures::static_assert_size!(Scalar, 24); // We want the `Debug` output to be readable as it is used by `derive(Debug)` for // all the Miri types. diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index bfa243612e96..4278ce823d0e 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1523,6 +1523,7 @@ pub enum BinOp { #[cfg(target_pointer_width = "64")] mod size_asserts { use super::*; + use rustc_data_structures::static_assert_size; // tidy-alphabetical-start static_assert_size!(AggregateKind<'_>, 32); static_assert_size!(Operand<'_>, 24); diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index ded2b93d6a15..3881723c5ec9 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -15,7 +15,7 @@ pub struct PlaceTy<'tcx> { // At least on 64 bit systems, `PlaceTy` should not be larger than two or three pointers. #[cfg(target_pointer_width = "64")] -static_assert_size!(PlaceTy<'_>, 16); +rustc_data_structures::static_assert_size!(PlaceTy<'_>, 16); impl<'tcx> PlaceTy<'tcx> { #[inline] diff --git a/compiler/rustc_middle/src/tests.rs b/compiler/rustc_middle/src/tests.rs index 49960cc0bb2a..0af75e6ff6c3 100644 --- a/compiler/rustc_middle/src/tests.rs +++ b/compiler/rustc_middle/src/tests.rs @@ -1,5 +1,3 @@ -use super::*; - // FIXME(#27438): right now the unit tests of rustc_middle don't refer to any actual // functions generated in rustc_data_structures (all // references are through generic functions), but statics are diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 3940d18bc591..a7d8ead56773 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -1210,6 +1210,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> { #[cfg(target_pointer_width = "64")] mod size_asserts { use super::*; + use rustc_data_structures::static_assert_size; // tidy-alphabetical-start static_assert_size!(Block, 48); static_assert_size!(Expr<'_>, 64); diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 3804dd6c4df8..5b7244f24879 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -560,7 +560,7 @@ impl<'tcx> ObligationCauseCode<'tcx> { // `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_pointer_width = "64")] -static_assert_size!(ObligationCauseCode<'_>, 48); +rustc_data_structures::static_assert_size!(ObligationCauseCode<'_>, 48); #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum StatementAsExpression { diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 7fe63cbe8240..a65b3a41ade3 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -23,7 +23,7 @@ pub use valtree::*; pub type ConstKind<'tcx> = IrConstKind>; #[cfg(target_pointer_width = "64")] -static_assert_size!(ConstKind<'_>, 32); +rustc_data_structures::static_assert_size!(ConstKind<'_>, 32); /// Use this rather than `ConstData`, whenever possible. #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)] @@ -63,7 +63,7 @@ pub struct ConstData<'tcx> { } #[cfg(target_pointer_width = "64")] -static_assert_size!(ConstData<'_>, 40); +rustc_data_structures::static_assert_size!(ConstData<'_>, 40); impl<'tcx> Const<'tcx> { #[inline] diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 60b242c9f666..7e49b0ac915c 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -72,4 +72,4 @@ pub enum Expr<'tcx> { } #[cfg(target_pointer_width = "64")] -static_assert_size!(Expr<'_>, 24); +rustc_data_structures::static_assert_size!(Expr<'_>, 24); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 3c73316865db..a279de2752b0 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1085,7 +1085,7 @@ struct ParamTag { reveal: traits::Reveal, } -impl_tag! { +rustc_data_structures::impl_tag! { impl Tag for ParamTag; ParamTag { reveal: traits::Reveal::UserFacing }, ParamTag { reveal: traits::Reveal::All }, diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 4b2d2af21e01..6f1be21d9266 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -29,9 +29,6 @@ #![feature(type_alias_impl_trait)] #![recursion_limit = "512"] // For rustdoc -#[cfg(target_pointer_width = "64")] -#[macro_use] -extern crate rustc_data_structures; #[macro_use] extern crate tracing; #[macro_use] diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 8cd9f39d5d83..1f10cb715430 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -73,7 +73,7 @@ pub struct PendingPredicateObligation<'tcx> { // `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_pointer_width = "64")] -static_assert_size!(PendingPredicateObligation<'_>, 72); +rustc_data_structures::static_assert_size!(PendingPredicateObligation<'_>, 72); impl<'tcx> FulfillmentContext<'tcx> { /// Creates a new fulfillment context. From 1ab34f063ba74e10ee1c33d9df85afbd5390596b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 29 Apr 2024 16:11:04 +1000 Subject: [PATCH 155/279] Remove `extern crate bitflags` from a couple of crates. --- compiler/rustc_middle/src/lib.rs | 2 -- compiler/rustc_middle/src/middle/codegen_fn_attrs.rs | 2 +- compiler/rustc_middle/src/ty/adt.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_type_ir/src/flags.rs | 2 +- compiler/rustc_type_ir/src/lib.rs | 3 --- 6 files changed, 4 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index da90ae5420fd..3c056ef0456c 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -65,8 +65,6 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#[macro_use] -extern crate bitflags; #[macro_use] extern crate tracing; #[macro_use] diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 8fabd80658ac..3fa5054baed1 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -49,7 +49,7 @@ pub struct CodegenFnAttrs { #[derive(Clone, Copy, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)] pub struct CodegenFnAttrFlags(u32); -bitflags! { +bitflags::bitflags! { impl CodegenFnAttrFlags: u32 { /// `#[cold]`: a hint to LLVM that this function, when called, is never on /// the hot path. diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 87b6a6079520..77da3fbe1d79 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -27,7 +27,7 @@ use super::{Destructor, FieldDef, GenericPredicates, Ty, TyCtxt, VariantDef, Var #[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)] pub struct AdtFlags(u16); -bitflags! { +bitflags::bitflags! { impl AdtFlags: u16 { const NO_ADT_FLAGS = 0; /// Indicates whether the ADT is an enum. diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a279de2752b0..f6146cfe5165 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1224,7 +1224,7 @@ pub struct Destructor { #[derive(Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] pub struct VariantFlags(u8); -bitflags! { +bitflags::bitflags! { impl VariantFlags: u8 { const NO_VARIANT_FLAGS = 0; /// Indicates whether the field list of this variant is `#[non_exhaustive]`. diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 997b410f819e..6a1ac642b70f 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -1,4 +1,4 @@ -bitflags! { +bitflags::bitflags! { /// Flags that we track on types. These flags are propagated upwards /// through the type during type construction, so that we can quickly check /// whether the type has various kinds of types in it without recursing diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 5aa4895633c2..ef7437c2542c 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -8,9 +8,6 @@ #[cfg(feature = "nightly")] extern crate self as rustc_type_ir; -#[macro_use] -extern crate bitflags; - #[cfg(feature = "nightly")] use rustc_data_structures::sync::Lrc; #[cfg(feature = "nightly")] From 52e9a23bdcd094cab07d13156a22d2d682bc63b6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 29 Apr 2024 16:18:37 +1000 Subject: [PATCH 156/279] Remove `extern crate smallvec` from a couple of crates. --- compiler/rustc_middle/src/lib.rs | 2 -- compiler/rustc_middle/src/mir/terminator.rs | 2 +- compiler/rustc_middle/src/traits/mod.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 2 +- compiler/rustc_middle/src/ty/walk.rs | 2 +- compiler/rustc_trait_selection/src/lib.rs | 2 -- compiler/rustc_trait_selection/src/traits/util.rs | 2 +- compiler/rustc_trait_selection/src/traits/vtable.rs | 2 +- 8 files changed, 6 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 3c056ef0456c..146dcf183b1d 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -67,8 +67,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate smallvec; #[cfg(test)] mod tests; diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index 5acf37325bce..f95afb199f7f 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -1,6 +1,6 @@ /// Functionality for terminators and helper types that appear in terminators. use rustc_hir::LangItem; -use smallvec::SmallVec; +use smallvec::{smallvec, SmallVec}; use super::TerminatorKind; use rustc_data_structures::packed::Pu128; diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 5b7244f24879..1ae037e09a75 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -26,7 +26,7 @@ use rustc_macros::{ use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; -use smallvec::SmallVec; +use smallvec::{smallvec, SmallVec}; use std::borrow::Cow; use std::hash::{Hash, Hasher}; diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index ae0de08f02fa..f5e973f85da1 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -22,7 +22,7 @@ use rustc_session::Limit; use rustc_span::sym; use rustc_target::abi::{Integer, IntegerType, Primitive, Size}; use rustc_target::spec::abi::Abi; -use smallvec::SmallVec; +use smallvec::{smallvec, SmallVec}; use std::{fmt, iter}; #[derive(Copy, Clone, Debug)] diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index 7069bdcbcb98..089e61749c3e 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -4,7 +4,7 @@ use crate::ty::{self, Ty}; use crate::ty::{GenericArg, GenericArgKind}; use rustc_data_structures::sso::SsoHashSet; -use smallvec::SmallVec; +use smallvec::{smallvec, SmallVec}; // The TypeWalker's stack is hot enough that it's worth going to some effort to // avoid heap allocations. diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 6f1be21d9266..5789ec2b1f18 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -33,8 +33,6 @@ extern crate tracing; #[macro_use] extern crate rustc_middle; -#[macro_use] -extern crate smallvec; pub mod errors; pub mod infer; diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index a8ca7d164a09..b2ba7854f188 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -10,7 +10,7 @@ use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_span::Span; -use smallvec::SmallVec; +use smallvec::{smallvec, SmallVec}; pub use rustc_infer::traits::util::*; diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 46a68508753c..178f3c63ef73 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -10,7 +10,7 @@ use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{self, GenericParamDefKind, ToPredicate, Ty, TyCtxt, VtblEntry}; use rustc_span::{sym, Span}; -use smallvec::SmallVec; +use smallvec::{smallvec, SmallVec}; use std::fmt::Debug; use std::ops::ControlFlow; From ae8c023983247044838a1a8b5f6fb5dd606fa68d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dorian=20P=C3=A9ron?= Date: Mon, 8 Apr 2024 14:44:25 +0000 Subject: [PATCH 157/279] mcdc-coverage: Add decision_depth field in structs Add decision_depth field to TVBitmapUpdate/CondBitmapUpdate statements Add decision_depth field to BcbMappingKinds MCDCBranch and MCDCDecision Add decision_depth field to MCDCBranchSpan and MCDCDecisionSpan --- .../src/coverageinfo/mod.rs | 8 ++--- compiler/rustc_middle/src/mir/coverage.rs | 20 +++++++---- compiler/rustc_middle/src/mir/pretty.rs | 17 ++++++--- .../rustc_mir_build/src/build/coverageinfo.rs | 2 ++ .../rustc_mir_transform/src/coverage/mod.rs | 35 +++++++++++-------- .../rustc_mir_transform/src/coverage/spans.rs | 8 ++++- .../src/coverage/spans/from_mir.rs | 27 +++++++++----- 7 files changed, 78 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index 03fc2ae425b0..eb1071448ce2 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -154,7 +154,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { CoverageKind::ExpressionUsed { id } => { func_coverage.mark_expression_id_seen(id); } - CoverageKind::CondBitmapUpdate { id, value, .. } => { + CoverageKind::CondBitmapUpdate { id, value, decision_depth } => { drop(coverage_map); assert_ne!( id.as_u32(), @@ -162,7 +162,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { "ConditionId of evaluated conditions should never be zero" ); let cond_bitmap = coverage_context - .try_get_mcdc_condition_bitmap(&instance, 0) + .try_get_mcdc_condition_bitmap(&instance, decision_depth) .expect("mcdc cond bitmap should have been allocated for updating"); let cond_loc = bx.const_i32(id.as_u32() as i32 - 1); let bool_value = bx.const_bool(value); @@ -170,10 +170,10 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { let hash = bx.const_u64(function_coverage_info.function_source_hash); bx.mcdc_condbitmap_update(fn_name, hash, cond_loc, cond_bitmap, bool_value); } - CoverageKind::TestVectorBitmapUpdate { bitmap_idx } => { + CoverageKind::TestVectorBitmapUpdate { bitmap_idx, decision_depth } => { drop(coverage_map); let cond_bitmap = coverage_context - .try_get_mcdc_condition_bitmap(&instance, 0) + .try_get_mcdc_condition_bitmap(&instance, decision_depth) .expect("mcdc cond bitmap should have been allocated for merging into the global bitmap"); let bitmap_bytes = bx.tcx().coverage_ids_info(instance.def).mcdc_bitmap_bytes; assert!(bitmap_idx < bitmap_bytes, "bitmap index of the decision out of range"); diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index 04011fd41948..6383074742d7 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -132,7 +132,7 @@ pub enum CoverageKind { /// /// If this statement does not survive MIR optimizations, the condition would never be /// taken as evaluated. - CondBitmapUpdate { id: ConditionId, value: bool }, + CondBitmapUpdate { id: ConditionId, value: bool, decision_depth: u16 }, /// Marks the point in MIR control flow represented by a evaluated decision. /// @@ -140,7 +140,7 @@ pub enum CoverageKind { /// /// If this statement does not survive MIR optimizations, the decision would never be /// taken as evaluated. - TestVectorBitmapUpdate { bitmap_idx: u32 }, + TestVectorBitmapUpdate { bitmap_idx: u32, decision_depth: u16 }, } impl Debug for CoverageKind { @@ -151,11 +151,17 @@ impl Debug for CoverageKind { BlockMarker { id } => write!(fmt, "BlockMarker({:?})", id.index()), CounterIncrement { id } => write!(fmt, "CounterIncrement({:?})", id.index()), ExpressionUsed { id } => write!(fmt, "ExpressionUsed({:?})", id.index()), - CondBitmapUpdate { id, value } => { - write!(fmt, "CondBitmapUpdate({:?}, {:?})", id.index(), value) + CondBitmapUpdate { id, value, decision_depth } => { + write!( + fmt, + "CondBitmapUpdate({:?}, {:?}, depth={:?})", + id.index(), + value, + decision_depth + ) } - TestVectorBitmapUpdate { bitmap_idx } => { - write!(fmt, "TestVectorUpdate({:?})", bitmap_idx) + TestVectorBitmapUpdate { bitmap_idx, decision_depth } => { + write!(fmt, "TestVectorUpdate({:?}, depth={:?})", bitmap_idx, decision_depth) } } } @@ -319,6 +325,7 @@ pub struct MCDCBranchSpan { pub condition_info: Option, pub true_marker: BlockMarkerId, pub false_marker: BlockMarkerId, + pub decision_depth: u16, } #[derive(Copy, Clone, Debug)] @@ -334,4 +341,5 @@ pub struct MCDCDecisionSpan { pub span: Span, pub conditions_num: usize, pub end_markers: Vec, + pub decision_depth: u16, } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 7a91d7383e51..32cd31834104 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -496,20 +496,27 @@ fn write_coverage_branch_info( )?; } - for coverage::MCDCBranchSpan { span, condition_info, true_marker, false_marker } in - mcdc_branch_spans + for coverage::MCDCBranchSpan { + span, + condition_info, + true_marker, + false_marker, + decision_depth, + } in mcdc_branch_spans { writeln!( w, - "{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?} }} => {span:?}", + "{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?}, depth: {decision_depth:?} }} => {span:?}", condition_info.map(|info| info.condition_id) )?; } - for coverage::MCDCDecisionSpan { span, conditions_num, end_markers } in mcdc_decision_spans { + for coverage::MCDCDecisionSpan { span, conditions_num, end_markers, decision_depth } in + mcdc_decision_spans + { writeln!( w, - "{INDENT}coverage mcdc decision {{ conditions_num: {conditions_num:?}, end: {end_markers:?} }} => {span:?}" + "{INDENT}coverage mcdc decision {{ conditions_num: {conditions_num:?}, end: {end_markers:?}, depth: {decision_depth:?} }} => {span:?}" )?; } diff --git a/compiler/rustc_mir_build/src/build/coverageinfo.rs b/compiler/rustc_mir_build/src/build/coverageinfo.rs index 9e9ccd3dc2d0..1818be2c1bd6 100644 --- a/compiler/rustc_mir_build/src/build/coverageinfo.rs +++ b/compiler/rustc_mir_build/src/build/coverageinfo.rs @@ -262,6 +262,7 @@ impl MCDCState { span, conditions_num: 0, end_markers: vec![], + decision_depth: 0, }), }; @@ -371,6 +372,7 @@ impl Builder<'_, '_> { condition_info, true_marker, false_marker, + decision_depth: 0, }); return; } diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 0b15c52c2814..a4c9e5ac0bcc 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -145,16 +145,17 @@ fn create_mappings<'tcx>( |BcbMapping { kind: bcb_mapping_kind, span }| { let kind = match *bcb_mapping_kind { BcbMappingKind::Code(bcb) => MappingKind::Code(term_for_bcb(bcb)), - BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info: None } => { - MappingKind::Branch { - true_term: term_for_bcb(true_bcb), - false_term: term_for_bcb(false_bcb), - } - } + BcbMappingKind::MCDCBranch { + true_bcb, false_bcb, condition_info: None, .. + } => MappingKind::Branch { + true_term: term_for_bcb(true_bcb), + false_term: term_for_bcb(false_bcb), + }, BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info: Some(mcdc_params), + .. } => MappingKind::MCDCBranch { true_term: term_for_bcb(true_bcb), false_term: term_for_bcb(false_bcb), @@ -246,24 +247,28 @@ fn inject_mcdc_statements<'tcx>( } // Inject test vector update first because `inject_statement` always insert new statement at head. - for (end_bcbs, bitmap_idx) in + for (end_bcbs, bitmap_idx, decision_depth) in coverage_spans.mappings.iter().filter_map(|mapping| match &mapping.kind { - BcbMappingKind::MCDCDecision { end_bcbs, bitmap_idx, .. } => { - Some((end_bcbs, *bitmap_idx)) + BcbMappingKind::MCDCDecision { end_bcbs, bitmap_idx, decision_depth, .. } => { + Some((end_bcbs, *bitmap_idx, *decision_depth)) } _ => None, }) { for end in end_bcbs { let end_bb = basic_coverage_blocks[*end].leader_bb(); - inject_statement(mir_body, CoverageKind::TestVectorBitmapUpdate { bitmap_idx }, end_bb); + inject_statement( + mir_body, + CoverageKind::TestVectorBitmapUpdate { bitmap_idx, decision_depth }, + end_bb, + ); } } - for (true_bcb, false_bcb, condition_id) in + for (true_bcb, false_bcb, condition_id, decision_depth) in coverage_spans.mappings.iter().filter_map(|mapping| match mapping.kind { - BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info } => { - Some((true_bcb, false_bcb, condition_info?.condition_id)) + BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info, decision_depth } => { + Some((true_bcb, false_bcb, condition_info?.condition_id, decision_depth)) } _ => None, }) @@ -271,13 +276,13 @@ fn inject_mcdc_statements<'tcx>( let true_bb = basic_coverage_blocks[true_bcb].leader_bb(); inject_statement( mir_body, - CoverageKind::CondBitmapUpdate { id: condition_id, value: true }, + CoverageKind::CondBitmapUpdate { id: condition_id, value: true, decision_depth }, true_bb, ); let false_bb = basic_coverage_blocks[false_bcb].leader_bb(); inject_statement( mir_body, - CoverageKind::CondBitmapUpdate { id: condition_id, value: false }, + CoverageKind::CondBitmapUpdate { id: condition_id, value: false, decision_depth }, false_bb, ); } diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 88f18b720857..b64b1212cecc 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -26,9 +26,15 @@ pub(super) enum BcbMappingKind { /// If `None`, this actually represents a normal branch mapping inserted /// for code that was too complex for MC/DC. condition_info: Option, + decision_depth: u16, }, /// Associates a mcdc decision with its join BCB. - MCDCDecision { end_bcbs: BTreeSet, bitmap_idx: u32, conditions_num: u16 }, + MCDCDecision { + end_bcbs: BTreeSet, + bitmap_idx: u32, + conditions_num: u16, + decision_depth: u16, + }, } #[derive(Debug)] diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs index 64f21d74b1cd..142dfc17fb8f 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs @@ -453,15 +453,25 @@ pub(super) fn extract_mcdc_mappings( Some((span, true_bcb, false_bcb)) }; - let mcdc_branch_filter_map = - |&MCDCBranchSpan { span: raw_span, true_marker, false_marker, condition_info }| { - check_branch_bcb(raw_span, true_marker, false_marker).map( - |(span, true_bcb, false_bcb)| BcbMapping { - kind: BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info }, - span, + let mcdc_branch_filter_map = |&MCDCBranchSpan { + span: raw_span, + true_marker, + false_marker, + condition_info, + decision_depth, + }| { + check_branch_bcb(raw_span, true_marker, false_marker).map(|(span, true_bcb, false_bcb)| { + BcbMapping { + kind: BcbMappingKind::MCDCBranch { + true_bcb, + false_bcb, + condition_info, + decision_depth, }, - ) - }; + span, + } + }) + }; let mut next_bitmap_idx = 0; @@ -482,6 +492,7 @@ pub(super) fn extract_mcdc_mappings( end_bcbs, bitmap_idx, conditions_num: decision.conditions_num as u16, + decision_depth: decision.decision_depth, }, span, }) From 60ca9b6e29975ab36e5460d761d99681bef0f130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dorian=20P=C3=A9ron?= Date: Wed, 10 Apr 2024 10:13:04 +0000 Subject: [PATCH 158/279] mcdc-coverage: Get decision_depth from THIR lowering Use decision context stack to handle nested decisions: - Introduce MCDCDecisionCtx - Use a stack of MCDCDecisionCtx to handle nested decisions --- .../src/coverageinfo/mod.rs | 3 +- compiler/rustc_middle/src/mir/coverage.rs | 3 + .../rustc_mir_build/src/build/coverageinfo.rs | 77 +++++++++++++++---- .../rustc_mir_build/src/build/matches/mod.rs | 6 ++ .../rustc_mir_transform/src/coverage/mod.rs | 11 +++ 5 files changed, 82 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index eb1071448ce2..679c6e1a2ff8 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -206,7 +206,8 @@ fn ensure_mcdc_parameters<'ll, 'tcx>( let fn_name = bx.get_pgo_func_name_var(instance); let hash = bx.const_u64(function_coverage_info.function_source_hash); let bitmap_bytes = bx.const_u32(function_coverage_info.mcdc_bitmap_bytes); - let cond_bitmap = bx.mcdc_parameters(fn_name, hash, bitmap_bytes, 1_u32); + let max_decision_depth = function_coverage_info.mcdc_max_decision_depth; + let cond_bitmap = bx.mcdc_parameters(fn_name, hash, bitmap_bytes, max_decision_depth as u32); bx.coverage_context() .expect("already checked above") .mcdc_condition_bitmap_map diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index 6383074742d7..a3fa69160a70 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -275,6 +275,9 @@ pub struct FunctionCoverageInfo { pub mcdc_bitmap_bytes: u32, pub expressions: IndexVec, pub mappings: Vec, + /// The depth of the deepest decision is used to know how many + /// temp condbitmaps should be allocated for the function. + pub mcdc_max_decision_depth: u16, } /// Branch information recorded during THIR-to-MIR lowering, and stored in MIR. diff --git a/compiler/rustc_mir_build/src/build/coverageinfo.rs b/compiler/rustc_mir_build/src/build/coverageinfo.rs index 1818be2c1bd6..a1c20fcfd836 100644 --- a/compiler/rustc_mir_build/src/build/coverageinfo.rs +++ b/compiler/rustc_mir_build/src/build/coverageinfo.rs @@ -101,10 +101,14 @@ impl BranchInfoBuilder { tcx: TyCtxt<'_>, true_marker: BlockMarkerId, false_marker: BlockMarkerId, - ) -> Option { + ) -> Option<(u16, ConditionInfo)> { let mcdc_state = self.mcdc_state.as_mut()?; + let decision_depth = mcdc_state.decision_depth(); let (mut condition_info, decision_result) = mcdc_state.take_condition(true_marker, false_marker); + // take_condition() returns Some for decision_result when the decision stack + // is empty, i.e. when all the conditions of the decision were instrumented, + // and the decision is "complete". if let Some(decision) = decision_result { match decision.conditions_num { 0 => { @@ -131,7 +135,7 @@ impl BranchInfoBuilder { } } } - condition_info + condition_info.map(|cond_info| (decision_depth, cond_info)) } fn add_two_way_branch<'tcx>( @@ -199,17 +203,32 @@ impl BranchInfoBuilder { /// This limit may be relaxed if the [upstream change](https://github.com/llvm/llvm-project/pull/82448) is merged. const MAX_CONDITIONS_NUM_IN_DECISION: usize = 6; -struct MCDCState { +#[derive(Default)] +struct MCDCDecisionCtx { /// To construct condition evaluation tree. decision_stack: VecDeque, processing_decision: Option, } +struct MCDCState { + decision_ctx_stack: Vec, +} + impl MCDCState { fn new_if_enabled(tcx: TyCtxt<'_>) -> Option { tcx.sess .instrument_coverage_mcdc() - .then(|| Self { decision_stack: VecDeque::new(), processing_decision: None }) + .then(|| Self { decision_ctx_stack: vec![MCDCDecisionCtx::default()] }) + } + + /// Decision depth is given as a u16 to reduce the size of the `CoverageKind`, + /// as it is very unlikely that the depth ever reaches 2^16. + #[inline] + fn decision_depth(&self) -> u16 { + u16::try_from( + self.decision_ctx_stack.len().checked_sub(1).expect("Unexpected empty decision stack"), + ) + .expect("decision depth did not fit in u16, this is likely to be an instrumentation error") } // At first we assign ConditionIds for each sub expression. @@ -253,20 +272,23 @@ impl MCDCState { // - If the op is AND, the "false_next" of LHS and RHS should be the parent's "false_next". While "true_next" of the LHS is the RHS, the "true next" of RHS is the parent's "true_next". // - If the op is OR, the "true_next" of LHS and RHS should be the parent's "true_next". While "false_next" of the LHS is the RHS, the "false next" of RHS is the parent's "false_next". fn record_conditions(&mut self, op: LogicalOp, span: Span) { - let decision = match self.processing_decision.as_mut() { + let decision_depth = self.decision_depth(); + let decision_ctx = + self.decision_ctx_stack.last_mut().expect("Unexpected empty decision_ctx_stack"); + let decision = match decision_ctx.processing_decision.as_mut() { Some(decision) => { decision.span = decision.span.to(span); decision } - None => self.processing_decision.insert(MCDCDecisionSpan { + None => decision_ctx.processing_decision.insert(MCDCDecisionSpan { span, conditions_num: 0, end_markers: vec![], - decision_depth: 0, + decision_depth, }), }; - let parent_condition = self.decision_stack.pop_back().unwrap_or_default(); + let parent_condition = decision_ctx.decision_stack.pop_back().unwrap_or_default(); let lhs_id = if parent_condition.condition_id == ConditionId::NONE { decision.conditions_num += 1; ConditionId::from(decision.conditions_num) @@ -306,8 +328,8 @@ impl MCDCState { } }; // We visit expressions tree in pre-order, so place the left-hand side on the top. - self.decision_stack.push_back(rhs); - self.decision_stack.push_back(lhs); + decision_ctx.decision_stack.push_back(rhs); + decision_ctx.decision_stack.push_back(lhs); } fn take_condition( @@ -315,10 +337,12 @@ impl MCDCState { true_marker: BlockMarkerId, false_marker: BlockMarkerId, ) -> (Option, Option) { - let Some(condition_info) = self.decision_stack.pop_back() else { + let decision_ctx = + self.decision_ctx_stack.last_mut().expect("Unexpected empty decision_ctx_stack"); + let Some(condition_info) = decision_ctx.decision_stack.pop_back() else { return (None, None); }; - let Some(decision) = self.processing_decision.as_mut() else { + let Some(decision) = decision_ctx.processing_decision.as_mut() else { bug!("Processing decision should have been created before any conditions are taken"); }; if condition_info.true_next_id == ConditionId::NONE { @@ -328,8 +352,8 @@ impl MCDCState { decision.end_markers.push(false_marker); } - if self.decision_stack.is_empty() { - (Some(condition_info), self.processing_decision.take()) + if decision_ctx.decision_stack.is_empty() { + (Some(condition_info), decision_ctx.processing_decision.take()) } else { (Some(condition_info), None) } @@ -365,14 +389,17 @@ impl Builder<'_, '_> { |block| branch_info.inject_block_marker(&mut self.cfg, source_info, block); let true_marker = inject_block_marker(then_block); let false_marker = inject_block_marker(else_block); - let condition_info = - branch_info.fetch_mcdc_condition_info(self.tcx, true_marker, false_marker); + let (decision_depth, condition_info) = branch_info + .fetch_mcdc_condition_info(self.tcx, true_marker, false_marker) + .map_or((0, None), |(decision_depth, condition_info)| { + (decision_depth, Some(condition_info)) + }); branch_info.mcdc_branch_spans.push(MCDCBranchSpan { span: source_info.span, condition_info, true_marker, false_marker, - decision_depth: 0, + decision_depth, }); return; } @@ -387,4 +414,20 @@ impl Builder<'_, '_> { mcdc_state.record_conditions(logical_op, span); } } + + pub(crate) fn mcdc_increment_depth_if_enabled(&mut self) { + if let Some(branch_info) = self.coverage_branch_info.as_mut() + && let Some(mcdc_state) = branch_info.mcdc_state.as_mut() + { + mcdc_state.decision_ctx_stack.push(MCDCDecisionCtx::default()); + }; + } + + pub(crate) fn mcdc_decrement_depth_if_enabled(&mut self) { + if let Some(branch_info) = self.coverage_branch_info.as_mut() + && let Some(mcdc_state) = branch_info.mcdc_state.as_mut() + { + mcdc_state.decision_ctx_stack.pop().expect("Unexpected empty decision stack"); + }; + } } diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index f46dceeeedf5..b36e97194c94 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -151,8 +151,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let mut block = block; let temp_scope = args.temp_scope_override.unwrap_or_else(|| this.local_scope()); let mutability = Mutability::Mut; + + // Increment the decision depth, in case we encounter boolean expressions + // further down. + this.mcdc_increment_depth_if_enabled(); let place = unpack!(block = this.as_temp(block, Some(temp_scope), expr_id, mutability)); + this.mcdc_decrement_depth_if_enabled(); + let operand = Operand::Move(Place::from(place)); let then_block = this.cfg.start_new_block(); diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index a4c9e5ac0bcc..159c099fac50 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -102,12 +102,23 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir: inject_mcdc_statements(mir_body, &basic_coverage_blocks, &coverage_spans); + let mcdc_max_decision_depth = coverage_spans + .mappings + .iter() + .filter_map(|bcb_mapping| match bcb_mapping.kind { + BcbMappingKind::MCDCDecision { decision_depth, .. } => Some(decision_depth), + _ => None, + }) + .max() + .unwrap_or(0); + mir_body.function_coverage_info = Some(Box::new(FunctionCoverageInfo { function_source_hash: hir_info.function_source_hash, num_counters: coverage_counters.num_counters(), mcdc_bitmap_bytes: coverage_spans.test_vector_bitmap_bytes(), expressions: coverage_counters.into_expressions(), mappings, + mcdc_max_decision_depth, })); } From eb422d5c7e6adccf83533ddb5a9836f6575bcd35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dorian=20P=C3=A9ron?= Date: Thu, 11 Apr 2024 10:08:11 +0000 Subject: [PATCH 159/279] tests(mcdc-coverage): Add tests for nested decision structures in mcdc_nested_if.rs --- tests/coverage/mcdc_nested_if.cov-map | 201 +++++++++++++++++++++ tests/coverage/mcdc_nested_if.coverage | 235 +++++++++++++++++++++++++ tests/coverage/mcdc_nested_if.rs | 70 ++++++++ 3 files changed, 506 insertions(+) create mode 100644 tests/coverage/mcdc_nested_if.cov-map create mode 100644 tests/coverage/mcdc_nested_if.coverage create mode 100644 tests/coverage/mcdc_nested_if.rs diff --git a/tests/coverage/mcdc_nested_if.cov-map b/tests/coverage/mcdc_nested_if.cov-map new file mode 100644 index 000000000000..2f35ffad8a98 --- /dev/null +++ b/tests/coverage/mcdc_nested_if.cov-map @@ -0,0 +1,201 @@ +Function name: mcdc_nested_if::doubly_nested_if_in_condition +Raw bytes (168): 0x[01, 01, 0e, 01, 05, 05, 11, 05, 11, 26, 19, 05, 11, 19, 1d, 19, 1d, 1d, 22, 26, 19, 05, 11, 11, 15, 09, 02, 0d, 37, 09, 02, 14, 01, 0f, 01, 01, 09, 28, 02, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 01, 02, 00, 10, 00, 36, 30, 11, 26, 01, 00, 02, 00, 10, 00, 11, 30, 15, 21, 02, 00, 00, 00, 15, 00, 36, 26, 00, 18, 00, 19, 28, 00, 02, 00, 18, 00, 1e, 30, 19, 22, 01, 02, 00, 00, 18, 00, 19, 19, 00, 1d, 00, 1e, 30, 1a, 1d, 02, 00, 00, 00, 1d, 00, 1e, 1a, 00, 21, 00, 25, 1f, 00, 2f, 00, 34, 2b, 00, 39, 00, 3e, 21, 00, 48, 00, 4c, 0d, 00, 4f, 02, 06, 37, 02, 0c, 02, 06, 33, 03, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 14 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Counter(1), rhs = Counter(4) +- expression 2 operands: lhs = Counter(1), rhs = Counter(4) +- expression 3 operands: lhs = Expression(9, Sub), rhs = Counter(6) +- expression 4 operands: lhs = Counter(1), rhs = Counter(4) +- expression 5 operands: lhs = Counter(6), rhs = Counter(7) +- expression 6 operands: lhs = Counter(6), rhs = Counter(7) +- expression 7 operands: lhs = Counter(7), rhs = Expression(8, Sub) +- expression 8 operands: lhs = Expression(9, Sub), rhs = Counter(6) +- expression 9 operands: lhs = Counter(1), rhs = Counter(4) +- expression 10 operands: lhs = Counter(4), rhs = Counter(5) +- expression 11 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 12 operands: lhs = Counter(3), rhs = Expression(13, Add) +- expression 13 operands: lhs = Counter(2), rhs = Expression(0, Sub) +Number of file 0 mappings: 20 +- Code(Counter(0)) at (prev + 15, 1) to (start + 1, 9) +- MCDCDecision { bitmap_idx: 2, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 78) +- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) + true = c1 + false = (c0 - c1) +- MCDCBranch { true: Counter(3), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 78) + true = c3 + false = c2 +- Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17) +- MCDCDecision { bitmap_idx: 1, conditions_num: 2 } at (prev + 0, 16) to (start + 0, 54) +- MCDCBranch { true: Counter(4), false: Expression(9, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17) + true = c4 + false = (c1 - c4) +- MCDCBranch { true: Counter(5), false: Counter(8), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 54) + true = c5 + false = c8 +- Code(Expression(9, Sub)) at (prev + 0, 24) to (start + 0, 25) + = (c1 - c4) +- MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 0, 24) to (start + 0, 30) +- MCDCBranch { true: Counter(6), false: Expression(8, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 24) to (start + 0, 25) + true = c6 + false = ((c1 - c4) - c6) +- Code(Counter(6)) at (prev + 0, 29) to (start + 0, 30) +- MCDCBranch { true: Expression(6, Sub), false: Counter(7), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 29) to (start + 0, 30) + true = (c6 - c7) + false = c7 +- Code(Expression(6, Sub)) at (prev + 0, 33) to (start + 0, 37) + = (c6 - c7) +- Code(Expression(7, Add)) at (prev + 0, 47) to (start + 0, 52) + = (c7 + ((c1 - c4) - c6)) +- Code(Expression(10, Add)) at (prev + 0, 57) to (start + 0, 62) + = (c4 + c5) +- Code(Counter(8)) at (prev + 0, 72) to (start + 0, 76) +- Code(Counter(3)) at (prev + 0, 79) to (start + 2, 6) +- Code(Expression(13, Add)) at (prev + 2, 12) to (start + 2, 6) + = (c2 + (c0 - c1)) +- Code(Expression(12, Add)) at (prev + 3, 1) to (start + 0, 2) + = (c3 + (c2 + (c0 - c1))) + +Function name: mcdc_nested_if::nested_if_in_condition +Raw bytes (120): 0x[01, 01, 0b, 01, 05, 05, 11, 05, 11, 1e, 15, 05, 11, 11, 15, 1e, 15, 05, 11, 09, 02, 0d, 2b, 09, 02, 0e, 01, 07, 01, 01, 09, 28, 01, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 00, 02, 00, 10, 00, 16, 30, 11, 1e, 01, 00, 02, 00, 10, 00, 11, 1e, 00, 15, 00, 16, 30, 15, 1a, 02, 00, 00, 00, 15, 00, 16, 17, 00, 19, 00, 1d, 1a, 00, 27, 00, 2c, 0d, 00, 2f, 02, 06, 2b, 02, 0c, 02, 06, 27, 03, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 11 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Counter(1), rhs = Counter(4) +- expression 2 operands: lhs = Counter(1), rhs = Counter(4) +- expression 3 operands: lhs = Expression(7, Sub), rhs = Counter(5) +- expression 4 operands: lhs = Counter(1), rhs = Counter(4) +- expression 5 operands: lhs = Counter(4), rhs = Counter(5) +- expression 6 operands: lhs = Expression(7, Sub), rhs = Counter(5) +- expression 7 operands: lhs = Counter(1), rhs = Counter(4) +- expression 8 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 9 operands: lhs = Counter(3), rhs = Expression(10, Add) +- expression 10 operands: lhs = Counter(2), rhs = Expression(0, Sub) +Number of file 0 mappings: 14 +- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 9) +- MCDCDecision { bitmap_idx: 1, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 46) +- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) + true = c1 + false = (c0 - c1) +- MCDCBranch { true: Counter(3), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 46) + true = c3 + false = c2 +- Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17) +- MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 0, 16) to (start + 0, 22) +- MCDCBranch { true: Counter(4), false: Expression(7, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17) + true = c4 + false = (c1 - c4) +- Code(Expression(7, Sub)) at (prev + 0, 21) to (start + 0, 22) + = (c1 - c4) +- MCDCBranch { true: Counter(5), false: Expression(6, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 22) + true = c5 + false = ((c1 - c4) - c5) +- Code(Expression(5, Add)) at (prev + 0, 25) to (start + 0, 29) + = (c4 + c5) +- Code(Expression(6, Sub)) at (prev + 0, 39) to (start + 0, 44) + = ((c1 - c4) - c5) +- Code(Counter(3)) at (prev + 0, 47) to (start + 2, 6) +- Code(Expression(10, Add)) at (prev + 2, 12) to (start + 2, 6) + = (c2 + (c0 - c1)) +- Code(Expression(9, Add)) at (prev + 3, 1) to (start + 0, 2) + = (c3 + (c2 + (c0 - c1))) + +Function name: mcdc_nested_if::nested_in_then_block_in_condition +Raw bytes (176): 0x[01, 01, 12, 01, 05, 05, 11, 05, 11, 3a, 15, 05, 11, 11, 15, 33, 19, 11, 15, 19, 1d, 19, 1d, 1d, 2e, 33, 19, 11, 15, 3a, 15, 05, 11, 09, 02, 0d, 47, 09, 02, 14, 01, 22, 01, 01, 09, 28, 02, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 00, 02, 00, 10, 00, 16, 30, 11, 3a, 01, 00, 02, 00, 10, 00, 11, 3a, 00, 15, 00, 16, 30, 15, 36, 02, 00, 00, 00, 15, 00, 16, 33, 00, 1c, 00, 1d, 28, 01, 02, 00, 1c, 00, 22, 30, 19, 2e, 01, 02, 00, 00, 1c, 00, 1d, 19, 00, 21, 00, 22, 30, 26, 1d, 02, 00, 00, 00, 21, 00, 22, 26, 00, 25, 00, 29, 2b, 00, 33, 00, 38, 36, 00, 44, 00, 49, 0d, 00, 4c, 02, 06, 47, 02, 0c, 02, 06, 43, 03, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 18 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Counter(1), rhs = Counter(4) +- expression 2 operands: lhs = Counter(1), rhs = Counter(4) +- expression 3 operands: lhs = Expression(14, Sub), rhs = Counter(5) +- expression 4 operands: lhs = Counter(1), rhs = Counter(4) +- expression 5 operands: lhs = Counter(4), rhs = Counter(5) +- expression 6 operands: lhs = Expression(12, Add), rhs = Counter(6) +- expression 7 operands: lhs = Counter(4), rhs = Counter(5) +- expression 8 operands: lhs = Counter(6), rhs = Counter(7) +- expression 9 operands: lhs = Counter(6), rhs = Counter(7) +- expression 10 operands: lhs = Counter(7), rhs = Expression(11, Sub) +- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(6) +- expression 12 operands: lhs = Counter(4), rhs = Counter(5) +- expression 13 operands: lhs = Expression(14, Sub), rhs = Counter(5) +- expression 14 operands: lhs = Counter(1), rhs = Counter(4) +- expression 15 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 16 operands: lhs = Counter(3), rhs = Expression(17, Add) +- expression 17 operands: lhs = Counter(2), rhs = Expression(0, Sub) +Number of file 0 mappings: 20 +- Code(Counter(0)) at (prev + 34, 1) to (start + 1, 9) +- MCDCDecision { bitmap_idx: 2, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 75) +- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) + true = c1 + false = (c0 - c1) +- MCDCBranch { true: Counter(3), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 75) + true = c3 + false = c2 +- Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17) +- MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 0, 16) to (start + 0, 22) +- MCDCBranch { true: Counter(4), false: Expression(14, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17) + true = c4 + false = (c1 - c4) +- Code(Expression(14, Sub)) at (prev + 0, 21) to (start + 0, 22) + = (c1 - c4) +- MCDCBranch { true: Counter(5), false: Expression(13, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 22) + true = c5 + false = ((c1 - c4) - c5) +- Code(Expression(12, Add)) at (prev + 0, 28) to (start + 0, 29) + = (c4 + c5) +- MCDCDecision { bitmap_idx: 1, conditions_num: 2 } at (prev + 0, 28) to (start + 0, 34) +- MCDCBranch { true: Counter(6), false: Expression(11, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 28) to (start + 0, 29) + true = c6 + false = ((c4 + c5) - c6) +- Code(Counter(6)) at (prev + 0, 33) to (start + 0, 34) +- MCDCBranch { true: Expression(9, Sub), false: Counter(7), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 33) to (start + 0, 34) + true = (c6 - c7) + false = c7 +- Code(Expression(9, Sub)) at (prev + 0, 37) to (start + 0, 41) + = (c6 - c7) +- Code(Expression(10, Add)) at (prev + 0, 51) to (start + 0, 56) + = (c7 + ((c4 + c5) - c6)) +- Code(Expression(13, Sub)) at (prev + 0, 68) to (start + 0, 73) + = ((c1 - c4) - c5) +- Code(Counter(3)) at (prev + 0, 76) to (start + 2, 6) +- Code(Expression(17, Add)) at (prev + 2, 12) to (start + 2, 6) + = (c2 + (c0 - c1)) +- Code(Expression(16, Add)) at (prev + 3, 1) to (start + 0, 2) + = (c3 + (c2 + (c0 - c1))) + +Function name: mcdc_nested_if::nested_single_condition_decision +Raw bytes (85): 0x[01, 01, 06, 01, 05, 05, 11, 05, 11, 09, 02, 0d, 17, 09, 02, 0b, 01, 17, 01, 04, 09, 28, 00, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 11, 0a, 00, 10, 00, 11, 11, 00, 14, 00, 19, 0a, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 17, 02, 0c, 02, 06, 13, 03, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 6 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Counter(1), rhs = Counter(4) +- expression 2 operands: lhs = Counter(1), rhs = Counter(4) +- expression 3 operands: lhs = Counter(2), rhs = Expression(0, Sub) +- expression 4 operands: lhs = Counter(3), rhs = Expression(5, Add) +- expression 5 operands: lhs = Counter(2), rhs = Expression(0, Sub) +Number of file 0 mappings: 11 +- Code(Counter(0)) at (prev + 23, 1) to (start + 4, 9) +- MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 4, 8) to (start + 0, 41) +- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) + true = c1 + false = (c0 - c1) +- MCDCBranch { true: Counter(3), false: Counter(2), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 41) + true = c3 + false = c2 +- Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17) +- Branch { true: Counter(4), false: Expression(2, Sub) } at (prev + 0, 16) to (start + 0, 17) + true = c4 + false = (c1 - c4) +- Code(Counter(4)) at (prev + 0, 20) to (start + 0, 25) +- Code(Expression(2, Sub)) at (prev + 0, 35) to (start + 0, 39) + = (c1 - c4) +- Code(Counter(3)) at (prev + 0, 42) to (start + 2, 6) +- Code(Expression(5, Add)) at (prev + 2, 12) to (start + 2, 6) + = (c2 + (c0 - c1)) +- Code(Expression(4, Add)) at (prev + 3, 1) to (start + 0, 2) + = (c3 + (c2 + (c0 - c1))) + diff --git a/tests/coverage/mcdc_nested_if.coverage b/tests/coverage/mcdc_nested_if.coverage new file mode 100644 index 000000000000..19529cd6aa43 --- /dev/null +++ b/tests/coverage/mcdc_nested_if.coverage @@ -0,0 +1,235 @@ + LL| |#![feature(coverage_attribute)] + LL| |//@ edition: 2021 + LL| |//@ min-llvm-version: 18 + LL| |//@ compile-flags: -Zcoverage-options=mcdc + LL| |//@ llvm-cov-flags: --show-mcdc + LL| | + LL| 4|fn nested_if_in_condition(a: bool, b: bool, c: bool) { + LL| 4| if a && if b || c { true } else { false } { + ^3 ^2 ^2 ^1 + ------------------ + |---> MC/DC Decision Region (LL:8) to (LL:46) + | + | Number of Conditions: 2 + | Condition C1 --> (LL:8) + | Condition C2 --> (LL:13) + | + | Executed MC/DC Test Vectors: + | + | C1, C2 Result + | 1 { F, - = F } + | 2 { T, F = F } + | 3 { T, T = T } + | + | C1-Pair: covered: (1,3) + | C2-Pair: covered: (2,3) + | MC/DC Coverage for Decision: 100.00% + | + |---> MC/DC Decision Region (LL:16) to (LL:22) + | + | Number of Conditions: 2 + | Condition C1 --> (LL:16) + | Condition C2 --> (LL:21) + | + | Executed MC/DC Test Vectors: + | + | C1, C2 Result + | 1 { F, F = F } + | 2 { T, - = T } + | 3 { F, T = T } + | + | C1-Pair: covered: (1,2) + | C2-Pair: covered: (1,3) + | MC/DC Coverage for Decision: 100.00% + | + ------------------ + LL| 2| say("yes"); + LL| 2| } else { + LL| 2| say("no"); + LL| 2| } + LL| 4|} + LL| | + LL| 4|fn doubly_nested_if_in_condition(a: bool, b: bool, c: bool, d: bool) { + LL| 4| if a && if b || if c && d { true } else { false } { false } else { true } { + ^3 ^2 ^1 ^1 ^1 ^2 ^1 + ------------------ + |---> MC/DC Decision Region (LL:8) to (LL:78) + | + | Number of Conditions: 2 + | Condition C1 --> (LL:8) + | Condition C2 --> (LL:13) + | + | Executed MC/DC Test Vectors: + | + | C1, C2 Result + | 1 { F, - = F } + | 2 { T, F = F } + | 3 { T, T = T } + | + | C1-Pair: covered: (1,3) + | C2-Pair: covered: (2,3) + | MC/DC Coverage for Decision: 100.00% + | + |---> MC/DC Decision Region (LL:16) to (LL:54) + | + | Number of Conditions: 2 + | Condition C1 --> (LL:16) + | Condition C2 --> (LL:21) + | + | Executed MC/DC Test Vectors: + | + | C1, C2 Result + | 1 { F, F = F } + | 2 { T, - = T } + | 3 { F, T = T } + | + | C1-Pair: covered: (1,2) + | C2-Pair: covered: (1,3) + | MC/DC Coverage for Decision: 100.00% + | + |---> MC/DC Decision Region (LL:24) to (LL:30) + | + | Number of Conditions: 2 + | Condition C1 --> (LL:24) + | Condition C2 --> (LL:29) + | + | Executed MC/DC Test Vectors: + | + | C1, C2 Result + | 1 { F, - = F } + | 2 { T, T = T } + | + | C1-Pair: covered: (1,2) + | C2-Pair: not covered + | MC/DC Coverage for Decision: 50.00% + | + ------------------ + LL| 1| say("yes"); + LL| 3| } else { + LL| 3| say("no"); + LL| 3| } + LL| 4|} + LL| | + LL| 3|fn nested_single_condition_decision(a: bool, b: bool) { + LL| 3| // Decision with only 1 decision should not be instrumented by MCDC because + LL| 3| // branch-coverage is equivalent to MCDC coverage in this case, and we don't + LL| 3| // want to waste bitmap space for this. + LL| 3| if a && if b { false } else { true } { + ^2 ^1 ^1 + ------------------ + |---> MC/DC Decision Region (LL:8) to (LL:41) + | + | Number of Conditions: 2 + | Condition C1 --> (LL:8) + | Condition C2 --> (LL:13) + | + | Executed MC/DC Test Vectors: + | + | C1, C2 Result + | 1 { F, - = F } + | 2 { T, F = F } + | 3 { T, T = T } + | + | C1-Pair: covered: (1,3) + | C2-Pair: covered: (2,3) + | MC/DC Coverage for Decision: 100.00% + | + ------------------ + LL| 1| say("yes"); + LL| 2| } else { + LL| 2| say("no"); + LL| 2| } + LL| 3|} + LL| | + LL| 7|fn nested_in_then_block_in_condition(a: bool, b: bool, c: bool, d: bool, e: bool) { + LL| 7| if a && if b || c { if d && e { true } else { false } } else { false } { + ^6 ^5 ^5 ^2 ^1 ^4 ^1 + ------------------ + |---> MC/DC Decision Region (LL:8) to (LL:75) + | + | Number of Conditions: 2 + | Condition C1 --> (LL:8) + | Condition C2 --> (LL:13) + | + | Executed MC/DC Test Vectors: + | + | C1, C2 Result + | 1 { F, - = F } + | 2 { T, F = F } + | 3 { T, T = T } + | + | C1-Pair: covered: (1,3) + | C2-Pair: covered: (2,3) + | MC/DC Coverage for Decision: 100.00% + | + |---> MC/DC Decision Region (LL:16) to (LL:22) + | + | Number of Conditions: 2 + | Condition C1 --> (LL:16) + | Condition C2 --> (LL:21) + | + | Executed MC/DC Test Vectors: + | + | C1, C2 Result + | 1 { F, F = F } + | 2 { T, - = T } + | 3 { F, T = T } + | + | C1-Pair: covered: (1,2) + | C2-Pair: covered: (1,3) + | MC/DC Coverage for Decision: 100.00% + | + |---> MC/DC Decision Region (LL:28) to (LL:34) + | + | Number of Conditions: 2 + | Condition C1 --> (LL:28) + | Condition C2 --> (LL:33) + | + | Executed MC/DC Test Vectors: + | + | C1, C2 Result + | 1 { F, - = F } + | 2 { T, F = F } + | 3 { T, T = T } + | + | C1-Pair: covered: (1,3) + | C2-Pair: covered: (2,3) + | MC/DC Coverage for Decision: 100.00% + | + ------------------ + LL| 1| say("yes"); + LL| 6| } else { + LL| 6| say("no"); + LL| 6| } + LL| 7|} + LL| | + LL| |#[coverage(off)] + LL| |fn main() { + LL| | nested_if_in_condition(true, false, false); + LL| | nested_if_in_condition(true, true, true); + LL| | nested_if_in_condition(true, false, true); + LL| | nested_if_in_condition(false, true, true); + LL| | + LL| | doubly_nested_if_in_condition(true, false, false, true); + LL| | doubly_nested_if_in_condition(true, true, true, true); + LL| | doubly_nested_if_in_condition(true, false, true, true); + LL| | doubly_nested_if_in_condition(false, true, true, true); + LL| | + LL| | nested_single_condition_decision(true, true); + LL| | nested_single_condition_decision(true, false); + LL| | nested_single_condition_decision(false, false); + LL| | + LL| | nested_in_then_block_in_condition(false, false, false, false, false); + LL| | nested_in_then_block_in_condition(true, false, false, false, false); + LL| | nested_in_then_block_in_condition(true, true, false, false, false); + LL| | nested_in_then_block_in_condition(true, false, true, false, false); + LL| | nested_in_then_block_in_condition(true, false, true, true, false); + LL| | nested_in_then_block_in_condition(true, false, true, false, true); + LL| | nested_in_then_block_in_condition(true, false, true, true, true); + LL| |} + LL| | + LL| |#[coverage(off)] + LL| |fn say(message: &str) { + LL| | core::hint::black_box(message); + LL| |} + diff --git a/tests/coverage/mcdc_nested_if.rs b/tests/coverage/mcdc_nested_if.rs new file mode 100644 index 000000000000..3d869771f75b --- /dev/null +++ b/tests/coverage/mcdc_nested_if.rs @@ -0,0 +1,70 @@ +#![feature(coverage_attribute)] +//@ edition: 2021 +//@ min-llvm-version: 18 +//@ compile-flags: -Zcoverage-options=mcdc +//@ llvm-cov-flags: --show-mcdc + +fn nested_if_in_condition(a: bool, b: bool, c: bool) { + if a && if b || c { true } else { false } { + say("yes"); + } else { + say("no"); + } +} + +fn doubly_nested_if_in_condition(a: bool, b: bool, c: bool, d: bool) { + if a && if b || if c && d { true } else { false } { false } else { true } { + say("yes"); + } else { + say("no"); + } +} + +fn nested_single_condition_decision(a: bool, b: bool) { + // Decision with only 1 decision should not be instrumented by MCDC because + // branch-coverage is equivalent to MCDC coverage in this case, and we don't + // want to waste bitmap space for this. + if a && if b { false } else { true } { + say("yes"); + } else { + say("no"); + } +} + +fn nested_in_then_block_in_condition(a: bool, b: bool, c: bool, d: bool, e: bool) { + if a && if b || c { if d && e { true } else { false } } else { false } { + say("yes"); + } else { + say("no"); + } +} + +#[coverage(off)] +fn main() { + nested_if_in_condition(true, false, false); + nested_if_in_condition(true, true, true); + nested_if_in_condition(true, false, true); + nested_if_in_condition(false, true, true); + + doubly_nested_if_in_condition(true, false, false, true); + doubly_nested_if_in_condition(true, true, true, true); + doubly_nested_if_in_condition(true, false, true, true); + doubly_nested_if_in_condition(false, true, true, true); + + nested_single_condition_decision(true, true); + nested_single_condition_decision(true, false); + nested_single_condition_decision(false, false); + + nested_in_then_block_in_condition(false, false, false, false, false); + nested_in_then_block_in_condition(true, false, false, false, false); + nested_in_then_block_in_condition(true, true, false, false, false); + nested_in_then_block_in_condition(true, false, true, false, false); + nested_in_then_block_in_condition(true, false, true, true, false); + nested_in_then_block_in_condition(true, false, true, false, true); + nested_in_then_block_in_condition(true, false, true, true, true); +} + +#[coverage(off)] +fn say(message: &str) { + core::hint::black_box(message); +} From a9022d4680cfa60d56aa240f093c65b7dd99481f Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Mon, 29 Apr 2024 10:13:42 +0100 Subject: [PATCH 160/279] Arm target doc wording tweaks based on review comments. --- .../src/platform-support/arm-none-eabi.md | 50 +++++++++++-------- .../platform-support/thumbv6m-none-eabi.md | 2 +- .../platform-support/thumbv7em-none-eabi.md | 6 +-- .../platform-support/thumbv7m-none-eabi.md | 2 +- .../thumbv8m.base-none-eabi.md | 2 +- .../thumbv8m.main-none-eabi.md | 2 +- 6 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/doc/rustc/src/platform-support/arm-none-eabi.md b/src/doc/rustc/src/platform-support/arm-none-eabi.md index 4bd1d68fb755..55d2f50b7621 100644 --- a/src/doc/rustc/src/platform-support/arm-none-eabi.md +++ b/src/doc/rustc/src/platform-support/arm-none-eabi.md @@ -30,24 +30,34 @@ ## Common Target Details -This documentation covers details that apply to a range of bare-metal target for -32-bit ARM CPUs. In addition, target specific details may be covered in their -own document. +This documentation covers details that apply to a range of bare-metal targets +for 32-bit ARM CPUs. In addition, target specific details may be covered in +their own document. If a target ends in `eabi`, that target uses the so-called *soft-float ABI*: functions which take `f32` or `f64` as arguments will have those values packed into integer registers. This means that an FPU is not required from an ABI -perspective, but within a function FPU instructions may still be used if the -code is compiled with a `target-cpu` or `target-feature` option that enables -FPU support. +perspective, but within a function floating-point instructions may still be used +if the code is compiled with a `target-cpu` or `target-feature` option that +enables FPU support. -If a target ends if `eabihf`, that target uses the so-called *hard-float ABI*: +If a target ends in `eabihf`, that target uses the so-called *hard-float ABI*: functions which take `f32` or `f64` as arguments will have them passed via FPU -registers. These targets therefore require the use of an FPU and will assume the -minimum support FPU for that architecture is available. More advanced FPU -instructions (e.g. ones that work on double-precision `f64` values) may be +registers. These targets therefore require the availability of an FPU and will +assume some baseline level of floating-point support is available (which can +vary depending on the target). More advanced floating-point instructions may be generated if the code is compiled with a `target-cpu` or `target-feature` option -that enables such additional FPU support. +that enables such additional FPU support. For example, if a given hard-float +target has baseline *single-precision* (`f32`) support in hardware, there may be +`target-cpu` or `target-feature` options that tell LLVM to assume your processor +in fact also has *double-precision* (`f64`) support. + +You may of course use the `f32` and `f64` types in your code, regardless of the +ABI being used, or the level of support your processor has for performing such +operations in hardware. Any floating-point operations that LLVM assumes your +processor cannot support will be lowered to library calls (like `__aeabi_dadd`) +which perform the floating-point operation in software using integer +instructions. ## Target CPU and Target Feature options @@ -61,7 +71,7 @@ It is important to note that selecting a *target-cpu* will typically enable *all* the optional features available from Arm on that model of CPU and your particular implementation of that CPU may not have those features available. In that case, you can use `-C target-feature=-option` to turn off the specific CPU -features you do not have available, leaving you with the optimised instruction +features you do not have available, leaving you with the optimized instruction scheduling and support for the features you do have. More details are available in the detailed target-specific documentation. @@ -76,13 +86,13 @@ uses (likely linker related ones): ```toml rustflags = [ # Usual Arm bare-metal linker setup - "-C", "link-arg=-Tlink.x", - "-C", "link-arg=--nmagic", + "-Clink-arg=-Tlink.x", + "-Clink-arg=--nmagic", # tell Rust we have a Cortex-M55 - "-C", "target-cpu=cortex-m55", + "-Ctarget-cpu=cortex-m55", # tell Rust our Cortex-M55 doesn't have Floating-Point M-Profile Vector # Extensions (but it does have everything else a Cortex-M55 could have). - "-C", "target-feature=-mve.fp" + "-Ctarget-feature=-mve.fp" ] [build] @@ -157,10 +167,10 @@ Most of `core` should work as expected, with the following notes: Rust programs are output as ELF files. -[atomic-load]: https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicU32.html#method.load -[atomic-store]: https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicU32.html#method.store -[fetch-add]: https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicU32.html#method.fetch_add -[compare-exchange]: https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicU32.html#method.compare_exchange +[atomic-load]: https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicU32.html#method.load +[atomic-store]: https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicU32.html#method.store +[fetch-add]: https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicU32.html#method.fetch_add +[compare-exchange]: https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicU32.html#method.compare_exchange ## Testing diff --git a/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md index f75194c815e0..32f2a573973f 100644 --- a/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md @@ -15,7 +15,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all `arm-none-eabi` targets. This target uses the soft-float ABI: functions which take `f32` or `f64` as -arguments will have those values packed into an integer registers. This is the +arguments will have those values packed into integer registers. This is the only option because there is no FPU support in [ARMv6-M]. [t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture diff --git a/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md index 632f1681bb9c..78a431fec933 100644 --- a/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md @@ -14,7 +14,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all `arm-none-eabi` targets. This target uses the soft-float ABI: functions which take `f32` or `f64` as -arguments will have those values packed into an integer registers. This target +arguments will have those values packed into integer registers. This target therefore does not require the use of an FPU (which is optional on Cortex-M4 and Cortex-M7), but an FPU can be optionally enabled if desired. See also the hard-float ABI version of this target @@ -52,7 +52,7 @@ The target CPU is `cortex-m4`. * All Cortex-M4 have DSP extensions * support is controlled by the `dsp` *target-feature* - * enabled by default with this *target-cpu* + * enabled by default with this *target* * Cortex-M4F has a single precision FPU * support is enabled by default with this *target-cpu* * disable support using the `+soft-float` feature @@ -63,7 +63,7 @@ The target CPU is `cortex-m7`. * All Cortex-M7 have DSP extensions * support is controlled by the `dsp` *target-feature* - * enabled by default with this *target-cpu* + * enabled by default with this *target* * Cortex-M7F have either a single-precision or double-precision FPU * double-precision support is enabled by default with this *target-cpu* * opt-out by using the `-f64` *target-feature* diff --git a/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md index 2c10f679f665..793e0d7d2de9 100644 --- a/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md @@ -13,7 +13,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all `arm-none-eabi` targets. This target uses the soft-float ABI: functions which take `f32` or `f64` as -arguments will have those values packed into an integer registers. This is the +arguments will have those values packed into integer registers. This is the only option because there is no FPU support in [ARMv7-M]. [t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture diff --git a/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md index 6e9d2329aa92..9733ce0e0aac 100644 --- a/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md @@ -13,7 +13,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all `arm-none-eabi` targets. This target uses the soft-float ABI: functions which take `f32` or `f64` as -arguments will have those values packed into an integer registers. This is the +arguments will have those values packed into integer registers. This is the only option because there is no FPU support in [ARMv6-M]. [t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture diff --git a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md index eca9a7b1a701..cbac897390e8 100644 --- a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md @@ -16,7 +16,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all `arm-none-eabi` targets. This target uses the soft-float ABI: functions which take `f32` or `f64` as -arguments will have those values packed into an integer registers. This target +arguments will have those values packed into integer registers. This target therefore does not require the use of an FPU (which is optional on Cortex-M33, Cortex-M55 and Cortex-M85), but an FPU can be optionally enabled if desired. See also the hard-float ABI version of this target From fa6b90cb8a9c7c5f437653040b6d1faf590ad5d9 Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Mon, 29 Apr 2024 10:32:04 +0100 Subject: [PATCH 161/279] arm target docs: collapsed eabi and eabihf into one --- src/doc/rustc/src/SUMMARY.md | 6 +- src/doc/rustc/src/platform-support.md | 4 +- .../src/platform-support/arm-none-eabi.md | 4 +- .../platform-support/thumbv7em-none-eabi.md | 28 +++-- .../platform-support/thumbv7em-none-eabihf.md | 67 ----------- .../thumbv8m.main-none-eabi.md | 57 +++++---- .../thumbv8m.main-none-eabihf.md | 113 ------------------ 7 files changed, 56 insertions(+), 223 deletions(-) delete mode 100644 src/doc/rustc/src/platform-support/thumbv7em-none-eabihf.md delete mode 100644 src/doc/rustc/src/platform-support/thumbv8m.main-none-eabihf.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 9dd68555bbe1..a3de28f80150 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -57,11 +57,9 @@ - [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md) - [thumbv6m-none-eabi](./platform-support/thumbv6m-none-eabi.md) - [thumbv7m-none-eabi](./platform-support/thumbv7m-none-eabi.md) - - [thumbv7em-none-eabi](./platform-support/thumbv7em-none-eabi.md) - - [thumbv7em-none-eabihf](./platform-support/thumbv7em-none-eabihf.md) + - [thumbv7em-none-eabi\*](./platform-support/thumbv7em-none-eabi.md) - [thumbv8m.base-none-eabi](./platform-support/thumbv8m.base-none-eabi.md) - - [thumbv8m.main-none-eabi](./platform-support/thumbv8m.main-none-eabi.md) - - [thumbv8m.main-none-eabihf](./platform-support/thumbv8m.main-none-eabihf.md) + - [thumbv8m.main-none-eabi\*](./platform-support/thumbv8m.main-none-eabi.md) - [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md) - [\*-nto-qnx-\*](platform-support/nto-qnx.md) - [*-unikraft-linux-musl](platform-support/unikraft-linux-musl.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 526b5a597899..cdab3d4401ef 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -180,13 +180,13 @@ target | std | notes `sparcv9-sun-solaris` | ✓ | SPARC Solaris 11, illumos [`thumbv6m-none-eabi`](platform-support/thumbv6m-none-eabi.md) | * | Bare ARMv6-M [`thumbv7em-none-eabi`](platform-support/thumbv7em-none-eabi.md) | * | Bare ARMv7E-M -[`thumbv7em-none-eabihf`](platform-support/thumbv7em-none-eabihf.md) | * | Bare ARMV7E-M, hardfloat +[`thumbv7em-none-eabihf`](platform-support/thumbv7em-none-eabi.md) | * | Bare ARMV7E-M, hardfloat [`thumbv7m-none-eabi`](platform-support/thumbv7m-none-eabi.md) | * | Bare ARMv7-M [`thumbv7neon-linux-androideabi`](platform-support/android.md) | ✓ | Thumb2-mode ARMv7-A Android with NEON `thumbv7neon-unknown-linux-gnueabihf` | ✓ | Thumb2-mode ARMv7-A Linux with NEON (kernel 4.4, glibc 2.23) [`thumbv8m.base-none-eabi`](platform-support/thumbv8m.base-none-eabi.md) | * | Bare ARMv8-M Baseline [`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare ARMv8-M Mainline -[`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabihf.md) | * | Bare ARMv8-M Mainline, hardfloat +[`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare ARMv8-M Mainline, hardfloat `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten `wasm32-unknown-unknown` | ✓ | WebAssembly `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename]) diff --git a/src/doc/rustc/src/platform-support/arm-none-eabi.md b/src/doc/rustc/src/platform-support/arm-none-eabi.md index 55d2f50b7621..64ae60172380 100644 --- a/src/doc/rustc/src/platform-support/arm-none-eabi.md +++ b/src/doc/rustc/src/platform-support/arm-none-eabi.md @@ -10,9 +10,9 @@ - Arm M-Profile Architectures - [`thumbv6m-none-eabi`](thumbv6m-none-eabi.md) - [`thumbv7m-none-eabi`](thumbv7m-none-eabi.md) - - [`thumbv7em-none-eabi`](thumbv7em-none-eabi.md) and [`thumbv7em-none-eabihf`](thumbv7em-none-eabihf.md) + - [`thumbv7em-none-eabi` and `thumbv7em-none-eabihf`](thumbv7em-none-eabi.md) - [`thumbv8m.base-none-eabi`](thumbv8m.base-none-eabi.md) - - [`thumbv8m.main-none-eabi`](thumbv8m.main-none-eabi.md) and [`thumbv8m.main-none-eabihf`](thumbv8m.main-none-eabihf.md) + - [`thumbv8m.main-none-eabi` and `thumbv8m.main-none-eabihf`](thumbv8m.main-none-eabi.md) - *Legacy* Arm Architectures - None diff --git a/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md index 78a431fec933..698c8ae7a655 100644 --- a/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md @@ -1,4 +1,4 @@ -# `thumbv7em-none-eabi` +# `thumbv7em-none-eabi` and `thumbv7em-none-eabihf` **Tier: 2** @@ -11,14 +11,8 @@ Processors in this family include the: * [Arm Cortex-M7][cortex-m7] and Arm Cortex-M7F See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all -`arm-none-eabi` targets. - -This target uses the soft-float ABI: functions which take `f32` or `f64` as -arguments will have those values packed into integer registers. This target -therefore does not require the use of an FPU (which is optional on Cortex-M4 and -Cortex-M7), but an FPU can be optionally enabled if desired. See also the -hard-float ABI version of this target -[`thumbv7em-none-eabihf`](thumbv7em-none-eabihf.md). +`arm-none-eabi` targets, in particular the difference between the `eabi` and +`eabihf` ABI. [t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture [ARMv7E-M]: https://developer.arm.com/documentation/ddi0403/latest/ @@ -36,16 +30,26 @@ See [the bare-metal Arm docs](arm-none-eabi.md#target-cpu-and-target-feature-options) for details on how to use these flags. -### Table of supported CPUs +### Table of supported CPUs for `thumbv7em-none-eabi` | CPU | FPU | DSP | Target CPU | Target Features | | ---------- | --- | --- | ----------- | --------------- | +| Any | No | Yes | None | None | | Cortex-M4 | No | Yes | `cortex-m4` | `+soft-float` | | Cortex-M4F | SP | Yes | `cortex-m4` | None | | Cortex-M7 | No | Yes | `cortex-m7` | `+soft-float` | | Cortex-M7F | SP | Yes | `cortex-m7` | `-fp64` | | Cortex-M7F | DP | Yes | `cortex-m7` | None | +### Table of supported CPUs for `thumbv7em-none-eabihf` + +| CPU | FPU | DSP | Target CPU | Target Features | +| ---------- | --- | --- | ----------- | --------------- | +| Any | SP | Yes | None | None | +| Cortex-M4F | SP | Yes | `cortex-m4` | None | +| Cortex-M7F | SP | Yes | `cortex-m7` | `-fp64` | +| Cortex-M7F | DP | Yes | `cortex-m7` | None | + ### Arm Cortex-M4 and Arm Cortex-M4F The target CPU is `cortex-m4`. @@ -55,7 +59,7 @@ The target CPU is `cortex-m4`. * enabled by default with this *target* * Cortex-M4F has a single precision FPU * support is enabled by default with this *target-cpu* - * disable support using the `+soft-float` feature + * disable support using the `+soft-float` feature (`eabi` only) ### Arm Cortex-M7 and Arm Cortex-M7F @@ -67,4 +71,4 @@ The target CPU is `cortex-m7`. * Cortex-M7F have either a single-precision or double-precision FPU * double-precision support is enabled by default with this *target-cpu* * opt-out by using the `-f64` *target-feature* - * disable support entirely using the `+soft-float` feature + * disable support entirely using the `+soft-float` feature (`eabi` only) diff --git a/src/doc/rustc/src/platform-support/thumbv7em-none-eabihf.md b/src/doc/rustc/src/platform-support/thumbv7em-none-eabihf.md deleted file mode 100644 index d4c93e3197c7..000000000000 --- a/src/doc/rustc/src/platform-support/thumbv7em-none-eabihf.md +++ /dev/null @@ -1,67 +0,0 @@ -# `thumbv7em-none-eabihf` - -**Tier: 2** - -Bare-metal target for CPUs in the [ARMv7E-M] architecture family that have an -FPU, supporting a subset of the [T32 ISA][t32-isa]. - -Processors in this family include the: - -* [Arm Cortex-M4F][cortex-m4] -* [Arm Cortex-M7F][cortex-m7] - -See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all -`arm-none-eabi` targets. - -This target uses the hard-float ABI: functions which take `f32` or `f64` as -arguments will have them passed via FPU registers. This target therefore -requires the use of an FPU (which is optional on Cortex-M4 and Cortex-M7). See -also the soft-float ABI version of this target -[`thumbv7em-none-eabi`](thumbv7em-none-eabi.md). - -[t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture -[ARMv7E-M]: https://developer.arm.com/documentation/ddi0403/latest/ -[cortex-m4]: https://developer.arm.com/Processors/Cortex-M4 -[cortex-m7]: https://developer.arm.com/Processors/Cortex-M7 - -## Target maintainers - -* [Rust Embedded Devices Working Group Cortex-M - Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org` - -## Target CPU and Target Feature options - -See [the bare-metal Arm -docs](arm-none-eabi.md#target-cpu-and-target-feature-options) for details on how -to use these flags. - -### Table of supported CPUs - -| CPU | FPU | DSP | Target CPU | Target Features | -| ---------- | --- | --- | ----------- | --------------- | -| Cortex-M4F | SP | Yes | `cortex-m4` | None | -| Cortex-M7F | SP | Yes | `cortex-m7` | `-fp64` | -| Cortex-M7F | DP | Yes | `cortex-m7` | None | - -### Arm Cortex-M4 and Arm Cortex-M4F - -The target CPU is `cortex-m4`. - -* All Cortex-M4 have DSP extensions - * support is controlled by the `dsp` *target-feature* - * enabled by default with this *target-cpu* -* Cortex-M4F has a single precision FPU - * support is enabled by default with this *target* - * support is required when using the hard-float ABI - -### Arm Cortex-M7 and Arm Cortex-M7F - -The target CPU is `cortex-m7`. - -* All Cortex-M7 have DSP extensions - * support is controlled by the `dsp` *target-feature* - * enabled by default with this *target-cpu* -* Cortex-M7F have either a single-precision or double-precision FPU - * single precision support is enabled by default with this *target* - * double-precision support is enabled by default with this *target-cpu* - * opt-out by using the `-f64` *target-feature* diff --git a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md index cbac897390e8..9541e1d582c2 100644 --- a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md @@ -1,4 +1,4 @@ -# `thumbv8m.main-none-eabi` +# `thumbv8m.main-none-eabi` and `thumbv8m.main-none-eabihf` **Tier: 2** @@ -13,14 +13,8 @@ Processors in this family include the: * [Arm Cortex-M85][cortex-m85] See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all -`arm-none-eabi` targets. - -This target uses the soft-float ABI: functions which take `f32` or `f64` as -arguments will have those values packed into integer registers. This target -therefore does not require the use of an FPU (which is optional on Cortex-M33, -Cortex-M55 and Cortex-M85), but an FPU can be optionally enabled if desired. See -also the hard-float ABI version of this target -[`thumbv8m.main-none-eabihf`](thumbv7em-none-eabihf.md). +`arm-none-eabi` targets, in particular the difference between the `eabi` and +`eabihf` ABI. [t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture [ARMv8-M]: https://developer.arm.com/documentation/ddi0553/latest/ @@ -40,18 +34,19 @@ See [the bare-metal Arm docs](arm-none-eabi.md#target-cpu-and-target-feature-options) for details on how to use these flags. -### Table of supported CPUs +### Table of supported CPUs for `thumbv8m.main-none-eabi` | CPU | FPU | DSP | MVE | Target CPU | Target Features | | ----------- | --- | --- | --------- | ------------- | --------------------- | -| Cortex-M33 | No | No | N/A | `cortex-m33` | `+soft-float,-dsp` | -| Cortex-M33 | No | Yes | N/A | `cortex-m33` | `+soft-float` | -| Cortex-M33 | SP | No | N/A | `cortex-m33` | `-dsp` | -| Cortex-M33 | SP | Yes | N/A | `cortex-m33` | None | -| Cortex-M35P | No | No | N/A | `cortex-m35p` | `+soft-float,-dsp` | -| Cortex-M35P | No | Yes | N/A | `cortex-m35p` | `+soft-float` | -| Cortex-M35P | SP | No | N/A | `cortex-m35p` | `-dsp` | -| Cortex-M35P | SP | Yes | N/A | `cortex-m35p` | None | +| Unspecified | No | No | No | None | None | +| Cortex-M33 | No | No | No | `cortex-m33` | `+soft-float,-dsp` | +| Cortex-M33 | No | Yes | No | `cortex-m33` | `+soft-float` | +| Cortex-M33 | SP | No | No | `cortex-m33` | `-dsp` | +| Cortex-M33 | SP | Yes | No | `cortex-m33` | None | +| Cortex-M35P | No | No | No | `cortex-m35p` | `+soft-float,-dsp` | +| Cortex-M35P | No | Yes | No | `cortex-m35p` | `+soft-float` | +| Cortex-M35P | SP | No | No | `cortex-m35p` | `-dsp` | +| Cortex-M35P | SP | Yes | No | `cortex-m35p` | None | | Cortex-M55 | No | Yes | No | `cortex-m55` | `+soft-float,-mve` | | Cortex-M55 | DP | Yes | No | `cortex-m55` | `-mve` | | Cortex-M55 | No | Yes | Int | `cortex-m55` | `+soft-float,-mve.fp` | @@ -63,6 +58,22 @@ to use these flags. | Cortex-M85 | DP | Yes | Int | `cortex-m85` | `-mve.fp` | | Cortex-M85 | DP | Yes | Int+Float | `cortex-m85` | None | +### Table of supported CPUs for `thumbv8m.main-none-eabihf` + +| CPU | FPU | DSP | MVE | Target CPU | Target Features | +| ----------- | --- | --- | --------- | ------------- | --------------------- | +| Unspecified | SP | No | No | None | None | +| Cortex-M33 | SP | No | No | `cortex-m33` | `-dsp` | +| Cortex-M33 | SP | Yes | No | `cortex-m33` | None | +| Cortex-M33P | SP | No | No | `cortex-m35p` | `-dsp` | +| Cortex-M33P | SP | Yes | No | `cortex-m35p` | None | +| Cortex-M55 | DP | Yes | No | `cortex-m55` | `-mve` | +| Cortex-M55 | DP | Yes | Int | `cortex-m55` | `-mve.fp` | +| Cortex-M55 | DP | Yes | Int+Float | `cortex-m55` | None | +| Cortex-M85 | DP | Yes | No | `cortex-m85` | `-mve` | +| Cortex-M85 | DP | Yes | Int | `cortex-m85` | `-mve.fp` | +| Cortex-M85 | DP | Yes | Int+Float | `cortex-m85` | None | + ### Arm Cortex-M33 The target CPU is `cortex-m33`. @@ -72,7 +83,7 @@ The target CPU is `cortex-m33`. * enabled by default with this *target-cpu* * Has an optional single precision FPU * support is enabled by default with this *target-cpu* - * disable support using the `+soft-float` feature + * disable support using the `+soft-float` feature (`eabi` only) ### Arm Cortex-M35P @@ -81,9 +92,9 @@ The target CPU is `cortex-m35p`. * Has optional DSP extensions * support is controlled by the `dsp` *target-feature* * enabled by default with this *target-cpu* -* Has a single precision FPU +* Has an optional single precision FPU * support is enabled by default with this *target-cpu* - * disable support using the `+soft-float` feature + * disable support using the `+soft-float` feature (`eabi` only) ### Arm Cortex-M55 @@ -95,7 +106,7 @@ The target CPU is `cortex-m55`. * Has an optional double-precision FPU that also supports half-precision FP16 values * support is enabled by default with this *target-cpu* - * disable support using the `+soft-float` feature + * disable support using the `+soft-float` feature (`eabi` only) * Has optional support for M-Profile Vector Extensions * Also known as *Helium Technology* * Available with only integer support, or both integer/float support @@ -114,7 +125,7 @@ The target CPU is `cortex-m85`. * Has an optional double-precision FPU that also supports half-precision FP16 values * support is enabled by default with this *target-cpu* - * disable support using the `+soft-float` feature + * disable support using the `+soft-float` feature (`eabi` only) * Has optional support for M-Profile Vector Extensions * Also known as *Helium Technology* * Available with only integer support, or both integer/float support diff --git a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabihf.md b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabihf.md deleted file mode 100644 index 8f353a8d3db0..000000000000 --- a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabihf.md +++ /dev/null @@ -1,113 +0,0 @@ -# `thumbv8m.main-none-eabihf` - -**Tier: 2** - -Bare-metal target for CPUs in the Mainline [ARMv8-M] architecture family, -supporting a subset of the [T32 ISA][t32-isa]. - -Processors in this family include the: - -* [Arm Cortex-M33F][cortex-m33] -* [Arm Cortex-M55F][cortex-m55] -* [Arm Cortex-M85F][cortex-m85] - -See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all -`arm-none-eabi` targets. - -This target uses the hard-float ABI: functions which take `f32` or `f64` as -arguments will have them passed via FPU registers. This target therefore -requires the use of an FPU (which is optional on Cortex-M33, Cortex-M55 and -Cortex-M85). See also the soft-float ABI version of this target -[`thumbv8m.main-none-eabi`](thumbv8m.main-none-eabi.md). - -[t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture -[ARMv8-M]: https://developer.arm.com/documentation/ddi0553/latest/ -[cortex-m33]: https://developer.arm.com/Processors/Cortex-M33 -[cortex-m55]: https://developer.arm.com/Processors/Cortex-M55 -[cortex-m85]: https://developer.arm.com/Processors/Cortex-M85 - -## Target maintainers - -* [Rust Embedded Devices Working Group Cortex-M - Team](https://github.com/rust-embedded), `cortex-m@teams.rust-embedded.org` - -## Target CPU and Target Feature options - -See [the bare-metal Arm -docs](arm-none-eabi.md#target-cpu-and-target-feature-options) for details on how -to use these flags. - -### Table of supported CPUs - -| CPU | FPU | DSP | MVE | Target CPU | Target Features | -| ----------- | --- | --- | --------- | ------------- | --------------------- | -| Cortex-M33 | SP | No | N/A | `cortex-m33` | `-dsp` | -| Cortex-M33 | SP | Yes | N/A | `cortex-m33` | None | -| Cortex-M33P | SP | No | N/A | `cortex-m35p` | `-dsp` | -| Cortex-M33P | SP | Yes | N/A | `cortex-m35p` | None | -| Cortex-M55 | DP | Yes | No | `cortex-m55` | `-mve` | -| Cortex-M55 | DP | Yes | Int | `cortex-m55` | `-mve.fp` | -| Cortex-M55 | DP | Yes | Int+Float | `cortex-m55` | None | -| Cortex-M85 | DP | Yes | No | `cortex-m85` | `-mve` | -| Cortex-M85 | DP | Yes | Int | `cortex-m85` | `-mve.fp` | -| Cortex-M85 | DP | Yes | Int+Float | `cortex-m85` | None | - -### Arm Cortex-M33 - -The target CPU is `cortex-m33`. - -* Has optional DSP extensions - * support is controlled by the `dsp` *target-feature* - * enabled by default with this *target-cpu* -* Has an optional single precision FPU - * support is enabled by default with this *target-cpu* - * support is required when using the hard-float ABI - -### Arm Cortex-M35P - -The target CPU is `cortex-m35p`. - -* Has optional DSP extensions - * support is controlled by the `dsp` *target-feature* - * enabled by default with this *target-cpu* -* Has a single precision FPU - * support is enabled by default with this *target-cpu* - * support is required when using the hard-float ABI - -### Arm Cortex-M55 - -The target CPU is `cortex-m55`. - -* Has DSP extensions - * support is controlled by the `dsp` *target-feature* - * enabled by default with this *target-cpu* -* Has an optional double-precision FPU that also supports half-precision FP16 - values - * support is enabled by default with this *target-cpu* - * support is required when using the hard-float ABI -* Has optional support for M-Profile Vector Extensions - * Also known as *Helium Technology* - * Available with only integer support, or both integer/float support - * The appropriate feature for the MVE is either `mve` (integer) or `mve.fp` - (float) - * `mve.fp` is enabled by default on this target CPU - * disable using `-mve.fp` (disable float MVE) or `-mve` (disable all MVE) - -### Arm Cortex-M85 - -The target CPU is `cortex-m85`. - -* Has DSP extensions - * support is controlled by the `dsp` *target-feature* - * enabled by default with this *target-cpu* -* Has an optional double-precision FPU that also supports half-precision FP16 - values - * support is enabled by default with this *target-cpu* - * support is required when using the hard-float ABI -* Has optional support for M-Profile Vector Extensions - * Also known as *Helium Technology* - * Available with only integer support, or both integer/float support - * The appropriate feature for the MVE is either `mve` (integer) or `mve.fp` - (float) - * `mve.fp` is enabled by default on this target CPU - * disable using `-mve.fp` (disable float MVE) or `-mve` (disable all MVE) From c8ff8a4dc7c9867c54df8f6d31120f4cd3923508 Mon Sep 17 00:00:00 2001 From: Sasha Pourcelot Date: Mon, 22 Apr 2024 18:48:41 +0200 Subject: [PATCH 162/279] Pretty-print parenthesis around binary in postfix match Signed-off-by: Sasha Pourcelot --- .../rustc_ast_pretty/src/pprust/state/expr.rs | 2 +- tests/pretty/postfix-match/precedence.pp | 34 +++++++++++++++++++ tests/pretty/postfix-match/precedence.rs | 34 +++++++++++++++++++ .../simple-matches.rs} | 0 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 tests/pretty/postfix-match/precedence.pp create mode 100644 tests/pretty/postfix-match/precedence.rs rename tests/pretty/{postfix-match.rs => postfix-match/simple-matches.rs} (100%) diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 4cbdc9f256df..b5bb781acdfe 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -488,7 +488,7 @@ impl<'a> State<'a> { self.space(); } MatchKind::Postfix => { - self.print_expr_as_cond(expr); + self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX, fixup); self.word_nbsp(".match"); } } diff --git a/tests/pretty/postfix-match/precedence.pp b/tests/pretty/postfix-match/precedence.pp new file mode 100644 index 000000000000..967aa7bc39ef --- /dev/null +++ b/tests/pretty/postfix-match/precedence.pp @@ -0,0 +1,34 @@ +#![feature(prelude_import)] +#![no_std] +#![feature(postfix_match)] +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; + +use std::ops::Add; + +//@ pretty-mode:expanded +//@ pp-exact:precedence.pp + +macro_rules! repro { ($e:expr) => { $e.match { _ => {} } }; } + +struct Struct {} + +impl Add for usize { + type Output = (); + fn add(self, _: Struct) -> () { () } +} +pub fn main() { + let a; + ( + { 1 } + 1).match { + _ => {} + }; + (4 as usize).match { _ => {} }; + (return).match { _ => {} }; + (a = 42).match { _ => {} }; + (|| {}).match { _ => {} }; + (42..101).match { _ => {} }; + (1 + Struct {}).match { _ => {} }; +} diff --git a/tests/pretty/postfix-match/precedence.rs b/tests/pretty/postfix-match/precedence.rs new file mode 100644 index 000000000000..ee947e161ddc --- /dev/null +++ b/tests/pretty/postfix-match/precedence.rs @@ -0,0 +1,34 @@ +#![feature(postfix_match)] + +use std::ops::Add; + +//@ pretty-mode:expanded +//@ pp-exact:precedence.pp + +macro_rules! repro { + ($e:expr) => { + $e.match { + _ => {} + } + }; +} + +struct Struct {} + +impl Add for usize { + type Output = (); + fn add(self, _: Struct) -> () { + () + } +} +pub fn main() { + let a; + + repro!({ 1 } + 1); + repro!(4 as usize); + repro!(return); + repro!(a = 42); + repro!(|| {}); + repro!(42..101); + repro!(1 + Struct {}); +} diff --git a/tests/pretty/postfix-match.rs b/tests/pretty/postfix-match/simple-matches.rs similarity index 100% rename from tests/pretty/postfix-match.rs rename to tests/pretty/postfix-match/simple-matches.rs From f9263374fb8143c7fa1850a43759249a73415cdf Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 29 Apr 2024 16:19:55 +1000 Subject: [PATCH 163/279] coverage: Replace boolean options with a `CoverageLevel` enum --- compiler/rustc_interface/src/tests.rs | 14 +++++------ compiler/rustc_session/src/config.rs | 24 +++++++++++++++---- compiler/rustc_session/src/options.rs | 14 ++++------- compiler/rustc_session/src/session.rs | 10 ++++---- src/doc/rustc/src/instrument-coverage.md | 6 +---- .../src/compiler-flags/coverage-options.md | 11 ++++++++- .../coverage-options.bad.stderr | 2 +- .../instrument-coverage/coverage-options.rs | 11 ++++----- 8 files changed, 53 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 68c7f187f52d..db150cc1f875 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -4,12 +4,12 @@ use rustc_data_structures::profiling::TimePassesFormat; use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig}; use rustc_session::config::{ build_configuration, build_session_options, rustc_optgroups, BranchProtection, CFGuard, Cfg, - CollapseMacroDebuginfo, CoverageOptions, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, - ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold, Input, - InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, - NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, - Passes, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, - WasiExecModel, + CollapseMacroDebuginfo, CoverageLevel, CoverageOptions, DebugInfo, DumpMonoStatsFormat, + ErrorOutputType, ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold, + Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, + LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, + PacRet, Passes, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, + SymbolManglingVersion, WasiExecModel, }; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; @@ -761,7 +761,7 @@ fn test_unstable_options_tracking_hash() { }) ); tracked!(codegen_backend, Some("abc".to_string())); - tracked!(coverage_options, CoverageOptions { branch: true, mcdc: true }); + tracked!(coverage_options, CoverageOptions { level: CoverageLevel::Mcdc }); tracked!(crate_attr, vec!["abc".to_string()]); tracked!(cross_crate_inline_threshold, InliningThreshold::Always); tracked!(debug_info_for_profiling, true); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 4f259960ac3a..a3978cc14a43 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -146,10 +146,26 @@ pub enum InstrumentCoverage { /// Individual flag values controlled by `-Z coverage-options`. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)] pub struct CoverageOptions { - /// Add branch coverage instrumentation. - pub branch: bool, - /// Add mcdc coverage instrumentation. - pub mcdc: bool, + pub level: CoverageLevel, + // Other boolean or enum-valued options might be added here. +} + +/// Controls whether branch coverage or MC/DC coverage is enabled. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +pub enum CoverageLevel { + /// Instrument for coverage at the MIR block level. + Block, + /// Also instrument branch points (includes block coverage). + Branch, + /// Instrument for MC/DC. Mostly a superset of branch coverage, but might + /// differ in some corner cases. + Mcdc, +} + +impl Default for CoverageLevel { + fn default() -> Self { + Self::Block + } } /// Settings for `-Z instrument-xray` flag. diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index e1474ee365b7..7355e5b69534 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -394,7 +394,7 @@ mod desc { pub const parse_optimization_fuel: &str = "crate=integer"; pub const parse_dump_mono_stats: &str = "`markdown` (default) or `json`"; pub const parse_instrument_coverage: &str = parse_bool; - pub const parse_coverage_options: &str = "either `no-branch`, `branch` or `mcdc`"; + pub const parse_coverage_options: &str = "`block` | `branch` | `mcdc`"; pub const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`"; pub const parse_unpretty: &str = "`string` or `string=string`"; pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number"; @@ -946,15 +946,9 @@ mod parse { for option in v.split(',') { match option { - "no-branch" => { - slot.branch = false; - slot.mcdc = false; - } - "branch" => slot.branch = true, - "mcdc" => { - slot.branch = true; - slot.mcdc = true; - } + "block" => slot.level = CoverageLevel::Block, + "branch" => slot.level = CoverageLevel::Branch, + "mcdc" => slot.level = CoverageLevel::Mcdc, _ => return false, } } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 2bc14b43234d..db01bb90d6fa 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1,8 +1,8 @@ use crate::code_stats::CodeStats; pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use crate::config::{ - self, CrateType, FunctionReturn, InstrumentCoverage, OptLevel, OutFileName, OutputType, - RemapPathScopeComponents, SwitchWithOptPath, + self, CoverageLevel, CrateType, FunctionReturn, InstrumentCoverage, OptLevel, OutFileName, + OutputType, RemapPathScopeComponents, SwitchWithOptPath, }; use crate::config::{ErrorOutputType, Input}; use crate::errors; @@ -349,11 +349,13 @@ impl Session { } pub fn instrument_coverage_branch(&self) -> bool { - self.instrument_coverage() && self.opts.unstable_opts.coverage_options.branch + self.instrument_coverage() + && self.opts.unstable_opts.coverage_options.level >= CoverageLevel::Branch } pub fn instrument_coverage_mcdc(&self) -> bool { - self.instrument_coverage() && self.opts.unstable_opts.coverage_options.mcdc + self.instrument_coverage() + && self.opts.unstable_opts.coverage_options.level >= CoverageLevel::Mcdc } pub fn is_sanitizer_cfi_enabled(&self) -> bool { diff --git a/src/doc/rustc/src/instrument-coverage.md b/src/doc/rustc/src/instrument-coverage.md index bbd81e7437c6..32dc992c42fa 100644 --- a/src/doc/rustc/src/instrument-coverage.md +++ b/src/doc/rustc/src/instrument-coverage.md @@ -348,11 +348,7 @@ $ llvm-cov report \ ## `-Z coverage-options=` -This unstable option provides finer control over some aspects of coverage -instrumentation. Pass one or more of the following values, separated by commas. - -- Either `no-branch`, `branch` or `mcdc` - - `branch` enables branch coverage instrumentation and `mcdc` further enables modified condition/decision coverage instrumentation. `no-branch` disables branch coverage instrumentation, which is same as do not pass `branch` or `mcdc`. +[This unstable option is described in the Unstable Book.](../unstable-book/compiler-flags/coverage-options.html) ## Other references diff --git a/src/doc/unstable-book/src/compiler-flags/coverage-options.md b/src/doc/unstable-book/src/compiler-flags/coverage-options.md index 5e192d9aca13..212788335502 100644 --- a/src/doc/unstable-book/src/compiler-flags/coverage-options.md +++ b/src/doc/unstable-book/src/compiler-flags/coverage-options.md @@ -5,4 +5,13 @@ This option controls details of the coverage instrumentation performed by Multiple options can be passed, separated by commas. Valid options are: -- `no-branch`, `branch` or `mcdc`: `branch` enables branch coverage instrumentation and `mcdc` further enables modified condition/decision coverage instrumentation. `no-branch` disables branch coverage instrumentation as well as mcdc instrumentation, which is same as do not pass `branch` or `mcdc`. +- `block`, `branch`, `mcdc`: + Sets the level of coverage instrumentation. + Setting the level will override any previously-specified level. + - `block` (default): + Blocks in the control-flow graph will be instrumented for coverage. + - `branch`: + In addition to block coverage, also enables branch coverage instrumentation. + - `mcdc`: + In addition to block and branch coverage, also enables MC/DC instrumentation. + (Branch coverage instrumentation may differ in some cases.) diff --git a/tests/ui/instrument-coverage/coverage-options.bad.stderr b/tests/ui/instrument-coverage/coverage-options.bad.stderr index f6e5421f8784..9e2c19e90d59 100644 --- a/tests/ui/instrument-coverage/coverage-options.bad.stderr +++ b/tests/ui/instrument-coverage/coverage-options.bad.stderr @@ -1,2 +1,2 @@ -error: incorrect value `bad` for unstable option `coverage-options` - either `no-branch`, `branch` or `mcdc` was expected +error: incorrect value `bad` for unstable option `coverage-options` - `block` | `branch` | `mcdc` was expected diff --git a/tests/ui/instrument-coverage/coverage-options.rs b/tests/ui/instrument-coverage/coverage-options.rs index 50c01ed29b5e..332da32e435d 100644 --- a/tests/ui/instrument-coverage/coverage-options.rs +++ b/tests/ui/instrument-coverage/coverage-options.rs @@ -1,20 +1,17 @@ //@ needs-profiler-support -//@ revisions: branch no-branch bad +//@ revisions: block branch bad //@ compile-flags -Cinstrument-coverage +//@ [block] check-pass +//@ [block] compile-flags: -Zcoverage-options=block + //@ [branch] check-pass //@ [branch] compile-flags: -Zcoverage-options=branch -//@ [no-branch] check-pass -//@ [no-branch] compile-flags: -Zcoverage-options=no-branch - //@ [mcdc] check-pass //@ [mcdc] compile-flags: -Zcoverage-options=mcdc //@ [bad] check-fail //@ [bad] compile-flags: -Zcoverage-options=bad -//@ [conflict] check-fail -//@ [conflict] compile-flags: -Zcoverage-options=no-branch,mcdc - fn main() {} From c6e946d0f0405fb7641b7dd2cad2d9432e2313f8 Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 29 Apr 2024 14:53:38 +0200 Subject: [PATCH 164/279] Change wording --- compiler/rustc_ast_lowering/messages.ftl | 2 +- tests/ui/issues/issue-43250.stderr | 4 ++-- tests/ui/lowering/expr-in-pat-issue-99380.stderr | 2 +- tests/ui/macros/vec-macro-in-pattern.stderr | 2 +- tests/ui/match/expr_before_ident_pat.stderr | 2 +- tests/ui/pattern/issue-92074-macro-ice.stderr | 6 +++--- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index aa5a85b9c4ca..10efe6fba655 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -5,7 +5,7 @@ ast_lowering_abi_specified_multiple_times = ast_lowering_arbitrary_expression_in_pattern = arbitrary expressions aren't allowed in patterns - .pattern_from_macro_note = the :expr fragment specifier forces the metavariable's content to be an expression + .pattern_from_macro_note = the `expr` fragment specifier forces the metavariable's content to be an expression ast_lowering_argument = argument diff --git a/tests/ui/issues/issue-43250.stderr b/tests/ui/issues/issue-43250.stderr index 01c22a9e7916..e74342b85adb 100644 --- a/tests/ui/issues/issue-43250.stderr +++ b/tests/ui/issues/issue-43250.stderr @@ -4,7 +4,7 @@ error: arbitrary expressions aren't allowed in patterns LL | m!(y); | ^ | - = note: the :expr fragment specifier forces the metavariable's content to be an expression + = note: the `expr` fragment specifier forces the metavariable's content to be an expression error: arbitrary expressions aren't allowed in patterns --> $DIR/issue-43250.rs:11:8 @@ -12,7 +12,7 @@ error: arbitrary expressions aren't allowed in patterns LL | m!(C); | ^ | - = note: the :expr fragment specifier forces the metavariable's content to be an expression + = note: the `expr` fragment specifier forces the metavariable's content to be an expression error: aborting due to 2 previous errors diff --git a/tests/ui/lowering/expr-in-pat-issue-99380.stderr b/tests/ui/lowering/expr-in-pat-issue-99380.stderr index 7438bba270c7..29438c9b0636 100644 --- a/tests/ui/lowering/expr-in-pat-issue-99380.stderr +++ b/tests/ui/lowering/expr-in-pat-issue-99380.stderr @@ -4,7 +4,7 @@ error: arbitrary expressions aren't allowed in patterns LL | foo!(Some(3)); | ^^^^^^^ | - = note: the :expr fragment specifier forces the metavariable's content to be an expression + = note: the `expr` fragment specifier forces the metavariable's content to be an expression error: aborting due to 1 previous error diff --git a/tests/ui/macros/vec-macro-in-pattern.stderr b/tests/ui/macros/vec-macro-in-pattern.stderr index 7c87f3b7b8e6..1a446b8c3edb 100644 --- a/tests/ui/macros/vec-macro-in-pattern.stderr +++ b/tests/ui/macros/vec-macro-in-pattern.stderr @@ -4,7 +4,7 @@ error: arbitrary expressions aren't allowed in patterns LL | Some(vec![43]) => {} | ^^^^^^^^ | - = note: the :expr fragment specifier forces the metavariable's content to be an expression + = note: the `expr` fragment specifier forces the metavariable's content to be an expression = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/match/expr_before_ident_pat.stderr b/tests/ui/match/expr_before_ident_pat.stderr index 2f59573b53f4..1657c51545cb 100644 --- a/tests/ui/match/expr_before_ident_pat.stderr +++ b/tests/ui/match/expr_before_ident_pat.stderr @@ -10,7 +10,7 @@ error: arbitrary expressions aren't allowed in patterns LL | funny!(a, a); | ^ | - = note: the :expr fragment specifier forces the metavariable's content to be an expression + = note: the `expr` fragment specifier forces the metavariable's content to be an expression error: aborting due to 2 previous errors diff --git a/tests/ui/pattern/issue-92074-macro-ice.stderr b/tests/ui/pattern/issue-92074-macro-ice.stderr index bf53eb4bbcd4..025592116e51 100644 --- a/tests/ui/pattern/issue-92074-macro-ice.stderr +++ b/tests/ui/pattern/issue-92074-macro-ice.stderr @@ -7,7 +7,7 @@ LL | () => { force_expr!(Vec::new()) } LL | assert!(matches!(x, En::A(make_vec!()))); | ----------- in this macro invocation | - = note: the :expr fragment specifier forces the metavariable's content to be an expression + = note: the `expr` fragment specifier forces the metavariable's content to be an expression = note: this error originates in the macro `make_vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: arbitrary expressions aren't allowed in patterns @@ -19,7 +19,7 @@ LL | () => { force_pat!(get_usize(), get_usize()) } LL | assert!(matches!(5, make_pat!())); | ----------- in this macro invocation | - = note: the :expr fragment specifier forces the metavariable's content to be an expression + = note: the `expr` fragment specifier forces the metavariable's content to be an expression = note: this error originates in the macro `make_pat` (in Nightly builds, run with -Z macro-backtrace for more info) error: arbitrary expressions aren't allowed in patterns @@ -31,7 +31,7 @@ LL | () => { force_pat!(get_usize(), get_usize()) } LL | assert!(matches!(5, make_pat!())); | ----------- in this macro invocation | - = note: the :expr fragment specifier forces the metavariable's content to be an expression + = note: the `expr` fragment specifier forces the metavariable's content to be an expression = note: this error originates in the macro `make_pat` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors From 52ea73a54064e4737a065c5060d15f74e18e04d3 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Mon, 29 Apr 2024 13:03:45 +0000 Subject: [PATCH 165/279] adapt a codegen test for llvm 19 No functional changes intended. Found by our experimental rust + LLVM @ HEAD bot: https://buildkite.com/llvm-project/rust-llvm-integrate-prototype/builds/27747#018f2570-018c-4b12-9c5a-38cf81453683/957-965 --- tests/codegen/ptr-read-metadata.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/codegen/ptr-read-metadata.rs b/tests/codegen/ptr-read-metadata.rs index 4c623dee5e1e..e3565c962f73 100644 --- a/tests/codegen/ptr-read-metadata.rs +++ b/tests/codegen/ptr-read-metadata.rs @@ -47,7 +47,7 @@ pub unsafe fn read_byte_assume_init(p: &MaybeUninit) -> u8 { p.assume_init_read() } -// CHECK-LABEL: define {{(dso_local )?}}noundef i32 @copy_char( +// CHECK-LABEL: define {{(dso_local )?}}noundef {{(range\(.*\) )?}}i32 @copy_char( #[no_mangle] pub unsafe fn copy_char(p: *const char) -> char { // CHECK-NOT: load @@ -58,7 +58,7 @@ pub unsafe fn copy_char(p: *const char) -> char { *p } -// CHECK-LABEL: define {{(dso_local )?}}noundef i32 @read_char( +// CHECK-LABEL: define {{(dso_local )?}}noundef {{(range\(.*\) )?}}i32 @read_char( #[no_mangle] pub unsafe fn read_char(p: *const char) -> char { // CHECK-NOT: load @@ -80,7 +80,7 @@ pub unsafe fn read_char_maybe_uninit(p: *const MaybeUninit) -> MaybeUninit p.read() } -// CHECK-LABEL: define {{(dso_local )?}}noundef i32 @read_char_assume_init( +// CHECK-LABEL: define {{(dso_local )?}}noundef {{(range\(.*\) )?}}i32 @read_char_assume_init( #[no_mangle] pub unsafe fn read_char_assume_init(p: &MaybeUninit) -> char { // CHECK-NOT: load From d31b7db8e46857853cc722de0158e73e16b09ed9 Mon Sep 17 00:00:00 2001 From: blyxyas Date: Mon, 29 Apr 2024 15:44:51 +0200 Subject: [PATCH 166/279] [Refactor] Rename Lint and LintGroup\'s is_loaded to is_externally_loaded --- compiler/rustc_driver_impl/src/lib.rs | 2 +- compiler/rustc_lint/src/context.rs | 18 ++++++++++-------- compiler/rustc_lint_defs/src/lib.rs | 9 +++++---- tests/ui/statics/nested_struct.rs | 4 ++-- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index b3cba4dbfc20..c1007ccd8e90 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -971,7 +971,7 @@ Available lint options: let lint_store = unerased_lint_store(sess); let (loaded, builtin): (Vec<_>, _) = - lint_store.get_lints().iter().cloned().partition(|&lint| lint.is_loaded); + lint_store.get_lints().iter().cloned().partition(|&lint| lint.is_externally_loaded); let loaded = sort_lints(sess, loaded); let builtin = sort_lints(sess, builtin); diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index d1dcfc524b55..d56d616809a3 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -110,7 +110,7 @@ struct LintAlias { struct LintGroup { lint_ids: Vec, - is_loaded: bool, + is_externally_loaded: bool, depr: Option, } @@ -159,7 +159,9 @@ impl LintStore { // Don't display deprecated lint groups. depr.is_none() }) - .map(|(k, LintGroup { lint_ids, is_loaded, .. })| (*k, lint_ids.clone(), *is_loaded)) + .map(|(k, LintGroup { lint_ids, is_externally_loaded, .. })| { + (*k, lint_ids.clone(), *is_externally_loaded) + }) } pub fn register_early_pass( @@ -218,7 +220,7 @@ impl LintStore { .entry(edition.lint_name()) .or_insert(LintGroup { lint_ids: vec![], - is_loaded: lint.is_loaded, + is_externally_loaded: lint.is_externally_loaded, depr: None, }) .lint_ids @@ -231,7 +233,7 @@ impl LintStore { .entry("future_incompatible") .or_insert(LintGroup { lint_ids: vec![], - is_loaded: lint.is_loaded, + is_externally_loaded: lint.is_externally_loaded, depr: None, }) .lint_ids @@ -246,7 +248,7 @@ impl LintStore { alias, LintGroup { lint_ids: vec![], - is_loaded: false, + is_externally_loaded: false, depr: Some(LintAlias { name: lint_name, silent: true }), }, ); @@ -254,21 +256,21 @@ impl LintStore { pub fn register_group( &mut self, - is_loaded: bool, + is_externally_loaded: bool, name: &'static str, deprecated_name: Option<&'static str>, to: Vec, ) { let new = self .lint_groups - .insert(name, LintGroup { lint_ids: to, is_loaded, depr: None }) + .insert(name, LintGroup { lint_ids: to, is_externally_loaded, depr: None }) .is_none(); if let Some(deprecated) = deprecated_name { self.lint_groups.insert( deprecated, LintGroup { lint_ids: vec![], - is_loaded, + is_externally_loaded, depr: Some(LintAlias { name, silent: false }), }, ); diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 7f200a7b623d..0569e30fd113 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -323,7 +323,8 @@ pub struct Lint { pub future_incompatible: Option, - pub is_loaded: bool, + /// `true` if this lint is being loaded by another tool (e.g. Clippy). + pub is_externally_loaded: bool, /// `Some` if this lint is feature gated, otherwise `None`. pub feature_gate: Option, @@ -468,7 +469,7 @@ impl Lint { default_level: Level::Forbid, desc: "", edition_lint_opts: None, - is_loaded: false, + is_externally_loaded: false, report_in_external_macro: false, future_incompatible: None, feature_gate: None, @@ -817,7 +818,7 @@ macro_rules! declare_lint { name: stringify!($NAME), default_level: $crate::$Level, desc: $desc, - is_loaded: false, + is_externally_loaded: false, $($v: true,)* $(feature_gate: Some($gate),)? $(future_incompatible: Some($crate::FutureIncompatibleInfo { @@ -859,7 +860,7 @@ macro_rules! declare_tool_lint { edition_lint_opts: None, report_in_external_macro: $external, future_incompatible: None, - is_loaded: true, + is_externally_loaded: true, $(feature_gate: Some($gate),)? crate_level_only: false, ..$crate::Lint::default_fields_for_macro() diff --git a/tests/ui/statics/nested_struct.rs b/tests/ui/statics/nested_struct.rs index f5819f50789c..6745e1029624 100644 --- a/tests/ui/statics/nested_struct.rs +++ b/tests/ui/statics/nested_struct.rs @@ -9,7 +9,7 @@ pub struct Lint { pub name: &'static str, pub desc: &'static str, pub report_in_external_macro: bool, - pub is_loaded: bool, + pub is_externally_loaded: bool, pub crate_level_only: bool, } @@ -17,7 +17,7 @@ static FOO: &Lint = &Lint { name: &"foo", desc: "desc", report_in_external_macro: false, - is_loaded: true, + is_externally_loaded: true, crate_level_only: false, }; From 5776aec662f3dd367ee04b5c9e34cba0c761df10 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 26 Apr 2024 12:36:33 -0400 Subject: [PATCH 167/279] Make names more accurate --- .../src/solve/assembly/mod.rs | 18 +++++++++++------- .../src/solve/normalizes_to/mod.rs | 15 ++++++++++----- .../src/solve/trait_goals.rs | 11 ++++++++--- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index 952215290932..6cecdeec9de2 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -56,7 +56,7 @@ pub(super) trait GoalKind<'tcx>: /// Consider a clause, which consists of a "assumption" and some "requirements", /// to satisfy a goal. If the requirements hold, then attempt to satisfy our /// goal by equating it with the assumption. - fn consider_implied_clause( + fn probe_and_consider_implied_clause( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, assumption: ty::Clause<'tcx>, @@ -73,7 +73,7 @@ pub(super) trait GoalKind<'tcx>: /// Consider a clause specifically for a `dyn Trait` self type. This requires /// additionally checking all of the supertraits and object bounds to hold, /// since they're not implied by the well-formedness of the object type. - fn consider_object_bound_candidate( + fn probe_and_consider_object_bound_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, assumption: ty::Clause<'tcx>, @@ -81,7 +81,7 @@ pub(super) trait GoalKind<'tcx>: Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| { let tcx = ecx.tcx(); let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else { - bug!("expected object type in `consider_object_bound_candidate`"); + bug!("expected object type in `probe_and_consider_object_bound_candidate`"); }; // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`? ecx.add_goals( @@ -557,7 +557,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { candidates: &mut Vec>, ) { for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() { - match G::consider_implied_clause(self, goal, assumption, []) { + match G::probe_and_consider_implied_clause(self, goal, assumption, []) { Ok(result) => { candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result }) } @@ -648,7 +648,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { for assumption in self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args) { - match G::consider_implied_clause(self, goal, assumption, []) { + match G::probe_and_consider_implied_clause(self, goal, assumption, []) { Ok(result) => { candidates.push(Candidate { source: CandidateSource::AliasBound, result }); } @@ -728,7 +728,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } ty::ExistentialPredicate::Projection(_) | ty::ExistentialPredicate::AutoTrait(_) => { - match G::consider_object_bound_candidate( + match G::probe_and_consider_object_bound_candidate( self, goal, bound.with_self_ty(tcx, self_ty), @@ -749,7 +749,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { if let Some(principal) = bounds.principal() { let principal_trait_ref = principal.with_self_ty(tcx, self_ty); self.walk_vtable(principal_trait_ref, |ecx, assumption, vtable_base, _| { - match G::consider_object_bound_candidate(ecx, goal, assumption.to_predicate(tcx)) { + match G::probe_and_consider_object_bound_candidate( + ecx, + goal, + assumption.to_predicate(tcx), + ) { Ok(result) => candidates.push(Candidate { source: CandidateSource::BuiltinImpl(BuiltinImplSource::Object { vtable_base, diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index c662ab23c53b..008927a23402 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -385,7 +385,12 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { // A built-in `Fn` impl only holds if the output is sized. // (FIXME: technically we only need to check this if the type is a fn ptr...) - Self::consider_implied_clause(ecx, goal, pred, [goal.with(tcx, output_is_sized_pred)]) + Self::probe_and_consider_implied_clause( + ecx, + goal, + pred, + [goal.with(tcx, output_is_sized_pred)], + ) } fn consider_builtin_async_fn_trait_candidates( @@ -461,7 +466,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { // A built-in `AsyncFn` impl only holds if the output is sized. // (FIXME: technically we only need to check this if the type is a fn ptr...) - Self::consider_implied_clause( + Self::probe_and_consider_implied_clause( ecx, goal, pred, @@ -623,7 +628,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { let term = args.as_coroutine().return_ty().into(); - Self::consider_implied_clause( + Self::probe_and_consider_implied_clause( ecx, goal, ty::ProjectionPredicate { @@ -654,7 +659,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { let term = args.as_coroutine().yield_ty().into(); - Self::consider_implied_clause( + Self::probe_and_consider_implied_clause( ecx, goal, ty::ProjectionPredicate { @@ -737,7 +742,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { bug!("unexpected associated item `<{self_ty} as Coroutine>::{name}`") }; - Self::consider_implied_clause( + Self::probe_and_consider_implied_clause( ecx, goal, ty::ProjectionPredicate { diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index f6d12a9a0138..07cdc4fb77a2 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -307,7 +307,12 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { .to_predicate(tcx); // A built-in `Fn` impl only holds if the output is sized. // (FIXME: technically we only need to check this if the type is a fn ptr...) - Self::consider_implied_clause(ecx, goal, pred, [goal.with(tcx, output_is_sized_pred)]) + Self::probe_and_consider_implied_clause( + ecx, + goal, + pred, + [goal.with(tcx, output_is_sized_pred)], + ) } fn consider_builtin_async_fn_trait_candidates( @@ -345,7 +350,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { .to_predicate(tcx); // A built-in `AsyncFn` impl only holds if the output is sized. // (FIXME: technically we only need to check this if the type is a fn ptr...) - Self::consider_implied_clause( + Self::probe_and_consider_implied_clause( ecx, goal, pred, @@ -521,7 +526,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { } let coroutine = args.as_coroutine(); - Self::consider_implied_clause( + Self::probe_and_consider_implied_clause( ecx, goal, ty::TraitRef::new(tcx, goal.predicate.def_id(), [self_ty, coroutine.resume_ty()]) From 7cf1c547c2ea1eb2ceae943b505faee6aca1e4d4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 26 Apr 2024 13:31:18 -0400 Subject: [PATCH 168/279] Actually use probes when needed and stop relying on existing outer probes --- compiler/rustc_middle/src/traits/solve.rs | 5 + .../rustc_middle/src/traits/solve/inspect.rs | 6 +- .../src/traits/solve/inspect/format.rs | 4 +- .../src/solve/assembly/mod.rs | 164 ++++---- .../src/solve/eval_ctxt/mod.rs | 28 +- .../src/solve/eval_ctxt/probe.rs | 23 +- .../src/solve/eval_ctxt/select.rs | 2 + .../src/solve/inspect/analyse.rs | 6 +- .../src/solve/normalizes_to/mod.rs | 78 ++-- .../src/solve/trait_goals.rs | 362 ++++++++++-------- .../src/traits/coherence.rs | 5 +- 11 files changed, 349 insertions(+), 334 deletions(-) diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs index 13504c6ae930..2c3f033925ab 100644 --- a/compiler/rustc_middle/src/traits/solve.rs +++ b/compiler/rustc_middle/src/traits/solve.rs @@ -332,4 +332,9 @@ pub enum CandidateSource { /// } /// ``` AliasBound, + /// A candidate that is registered only during coherence to represent some + /// yet-unknown impl that could be produced downstream without violating orphan + /// rules. + // FIXME: Merge this with the forced ambiguity candidates, so those don't use `Misc`. + CoherenceUnknowable, } diff --git a/compiler/rustc_middle/src/traits/solve/inspect.rs b/compiler/rustc_middle/src/traits/solve/inspect.rs index 1b2e2781bfe7..66542431149f 100644 --- a/compiler/rustc_middle/src/traits/solve/inspect.rs +++ b/compiler/rustc_middle/src/traits/solve/inspect.rs @@ -141,10 +141,6 @@ pub enum ProbeKind<'tcx> { TryNormalizeNonRigid { result: QueryResult<'tcx> }, /// Probe entered when normalizing the self ty during candidate assembly NormalizedSelfTyAssembly, - /// Some candidate to prove the current goal. - /// - /// FIXME: Remove this in favor of always using more strongly typed variants. - MiscCandidate { name: &'static str, result: QueryResult<'tcx> }, /// A candidate for proving a trait or alias-relate goal. TraitCandidate { source: CandidateSource, result: QueryResult<'tcx> }, /// Used in the probe that wraps normalizing the non-self type for the unsize @@ -154,4 +150,6 @@ pub enum ProbeKind<'tcx> { /// do a probe to find out what projection type(s) may be used to prove that /// the source type upholds all of the target type's object bounds. UpcastProjectionCompatibility, + /// Try to unify an opaque type with an existing + OpaqueTypeStorageLookup, } diff --git a/compiler/rustc_middle/src/traits/solve/inspect/format.rs b/compiler/rustc_middle/src/traits/solve/inspect/format.rs index 2e2d1df8d193..91f0880fd208 100644 --- a/compiler/rustc_middle/src/traits/solve/inspect/format.rs +++ b/compiler/rustc_middle/src/traits/solve/inspect/format.rs @@ -112,8 +112,8 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> { ProbeKind::UpcastProjectionCompatibility => { write!(self.f, "PROBING FOR PROJECTION COMPATIBILITY FOR UPCASTING:") } - ProbeKind::MiscCandidate { name, result } => { - write!(self.f, "CANDIDATE {name}: {result:?}") + ProbeKind::OpaqueTypeStorageLookup => { + write!(self.f, "PROBING FOR AN EXISTING OPAQUE:") } ProbeKind::TraitCandidate { source, result } => { write!(self.f, "CANDIDATE {source:?}: {result:?}") diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index 6cecdeec9de2..b082b0bd4c8a 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -48,21 +48,23 @@ pub(super) trait GoalKind<'tcx>: /// [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]). fn probe_and_match_goal_against_assumption( ecx: &mut EvalCtxt<'_, 'tcx>, + source: CandidateSource, goal: Goal<'tcx, Self>, assumption: ty::Clause<'tcx>, then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// Consider a clause, which consists of a "assumption" and some "requirements", /// to satisfy a goal. If the requirements hold, then attempt to satisfy our /// goal by equating it with the assumption. fn probe_and_consider_implied_clause( ecx: &mut EvalCtxt<'_, 'tcx>, + source: CandidateSource, goal: Goal<'tcx, Self>, assumption: ty::Clause<'tcx>, requirements: impl IntoIterator>>, - ) -> QueryResult<'tcx> { - Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| { + ) -> Result, NoSolution> { + Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| { // FIXME(-Znext-solver=coinductive): check whether this should be // `GoalSource::ImplWhereBound` for any caller. ecx.add_goals(GoalSource::Misc, requirements); @@ -75,10 +77,11 @@ pub(super) trait GoalKind<'tcx>: /// since they're not implied by the well-formedness of the object type. fn probe_and_consider_object_bound_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, + source: CandidateSource, goal: Goal<'tcx, Self>, assumption: ty::Clause<'tcx>, - ) -> QueryResult<'tcx> { - Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| { + ) -> Result, NoSolution> { + Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| { let tcx = ecx.tcx(); let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else { bug!("expected object type in `probe_and_consider_object_bound_candidate`"); @@ -112,7 +115,7 @@ pub(super) trait GoalKind<'tcx>: fn consider_error_guaranteed_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, guar: ErrorGuaranteed, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// A type implements an `auto trait` if its components do as well. /// @@ -121,13 +124,13 @@ pub(super) trait GoalKind<'tcx>: fn consider_auto_trait_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// A trait alias holds if the RHS traits and `where` clauses hold. fn consider_trait_alias_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// A type is `Sized` if its tail component is `Sized`. /// @@ -136,7 +139,7 @@ pub(super) trait GoalKind<'tcx>: fn consider_builtin_sized_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// A type is `Copy` or `Clone` if its components are `Copy` or `Clone`. /// @@ -145,20 +148,20 @@ pub(super) trait GoalKind<'tcx>: fn consider_builtin_copy_clone_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// A type is `PointerLike` if we can compute its layout, and that layout /// matches the layout of `usize`. fn consider_builtin_pointer_like_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// A type is a `FnPtr` if it is of `FnPtr` type. fn consider_builtin_fn_ptr_trait_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// A callable type (a closure, fn def, or fn ptr) is known to implement the `Fn` /// family of traits where `A` is given by the signature of the type. @@ -166,7 +169,7 @@ pub(super) trait GoalKind<'tcx>: ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, kind: ty::ClosureKind, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// An async closure is known to implement the `AsyncFn` family of traits /// where `A` is given by the signature of the type. @@ -174,7 +177,7 @@ pub(super) trait GoalKind<'tcx>: ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, kind: ty::ClosureKind, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// Compute the built-in logic of the `AsyncFnKindHelper` helper trait, which /// is used internally to delay computation for async closures until after @@ -182,13 +185,13 @@ pub(super) trait GoalKind<'tcx>: fn consider_builtin_async_fn_kind_helper_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// `Tuple` is implemented if the `Self` type is a tuple. fn consider_builtin_tuple_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// `Pointee` is always implemented. /// @@ -198,7 +201,7 @@ pub(super) trait GoalKind<'tcx>: fn consider_builtin_pointee_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// A coroutine (that comes from an `async` desugaring) is known to implement /// `Future`, where `O` is given by the coroutine's return type @@ -206,7 +209,7 @@ pub(super) trait GoalKind<'tcx>: fn consider_builtin_future_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// A coroutine (that comes from a `gen` desugaring) is known to implement /// `Iterator`, where `O` is given by the generator's yield type @@ -214,19 +217,19 @@ pub(super) trait GoalKind<'tcx>: fn consider_builtin_iterator_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// A coroutine (that comes from a `gen` desugaring) is known to implement /// `FusedIterator` fn consider_builtin_fused_iterator_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; fn consider_builtin_async_iterator_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// A coroutine (that doesn't come from an `async` or `gen` desugaring) is known to /// implement `Coroutine`, given the resume, yield, @@ -234,27 +237,27 @@ pub(super) trait GoalKind<'tcx>: fn consider_builtin_coroutine_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; fn consider_builtin_discriminant_kind_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; fn consider_builtin_async_destruct_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; fn consider_builtin_destruct_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; fn consider_builtin_transmute_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx>; + ) -> Result, NoSolution>; /// Consider (possibly several) candidates to upcast or unsize a type to another /// type, excluding the coercion of a sized type into a `dyn Trait`. @@ -266,7 +269,7 @@ pub(super) trait GoalKind<'tcx>: fn consider_structural_builtin_unsize_candidates( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> Vec<(CanonicalResponse<'tcx>, BuiltinImplSource)>; + ) -> Vec>; } impl<'tcx> EvalCtxt<'_, 'tcx> { @@ -282,7 +285,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { if normalized_self_ty.is_ty_var() { debug!("self type has been normalized to infer"); - return self.forced_ambiguity(MaybeCause::Ambiguity); + return self.forced_ambiguity(MaybeCause::Ambiguity).into_iter().collect(); } let goal = @@ -315,7 +318,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { candidates } - fn forced_ambiguity(&mut self, cause: MaybeCause) -> Vec> { + pub(super) fn forced_ambiguity( + &mut self, + cause: MaybeCause, + ) -> Result, NoSolution> { // This may fail if `try_evaluate_added_goals` overflows because it // fails to reach a fixpoint but ends up getting an error after // running for some additional step. @@ -323,10 +329,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // cc trait-system-refactor-initiative#105 let source = CandidateSource::BuiltinImpl(BuiltinImplSource::Misc); let certainty = Certainty::Maybe(cause); - let result = self - .probe_trait_candidate(source) - .enter(|this| this.evaluate_added_goals_and_make_canonical_response(certainty)); - if let Ok(cand) = result { vec![cand] } else { vec![] } + self.probe_trait_candidate(source) + .enter(|this| this.evaluate_added_goals_and_make_canonical_response(certainty)) } #[instrument(level = "debug", skip_all)] @@ -533,20 +537,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Err(NoSolution) }; - match result { - Ok(result) => candidates.push(Candidate { - source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), - result, - }), - Err(NoSolution) => (), - } + candidates.extend(result); // There may be multiple unsize candidates for a trait with several supertraits: // `trait Foo: Bar + Bar` and `dyn Foo: Unsize>` if lang_items.unsize_trait() == Some(trait_def_id) { - for (result, source) in G::consider_structural_builtin_unsize_candidates(self, goal) { - candidates.push(Candidate { source: CandidateSource::BuiltinImpl(source), result }); - } + candidates.extend(G::consider_structural_builtin_unsize_candidates(self, goal)); } } @@ -557,12 +553,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { candidates: &mut Vec>, ) { for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() { - match G::probe_and_consider_implied_clause(self, goal, assumption, []) { - Ok(result) => { - candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result }) - } - Err(NoSolution) => (), - } + candidates.extend(G::probe_and_consider_implied_clause( + self, + CandidateSource::ParamEnv(i), + goal, + assumption, + [], + )); } } @@ -648,12 +645,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { for assumption in self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args) { - match G::probe_and_consider_implied_clause(self, goal, assumption, []) { - Ok(result) => { - candidates.push(Candidate { source: CandidateSource::AliasBound, result }); - } - Err(NoSolution) => {} - } + candidates.extend(G::probe_and_consider_implied_clause( + self, + CandidateSource::AliasBound, + goal, + assumption, + [], + )); } if kind != ty::Projection { @@ -728,17 +726,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } ty::ExistentialPredicate::Projection(_) | ty::ExistentialPredicate::AutoTrait(_) => { - match G::probe_and_consider_object_bound_candidate( + candidates.extend(G::probe_and_consider_object_bound_candidate( self, + CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, bound.with_self_ty(tcx, self_ty), - ) { - Ok(result) => candidates.push(Candidate { - source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), - result, - }), - Err(NoSolution) => (), - } + )); } } } @@ -749,19 +742,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { if let Some(principal) = bounds.principal() { let principal_trait_ref = principal.with_self_ty(tcx, self_ty); self.walk_vtable(principal_trait_ref, |ecx, assumption, vtable_base, _| { - match G::probe_and_consider_object_bound_candidate( + candidates.extend(G::probe_and_consider_object_bound_candidate( ecx, + CandidateSource::BuiltinImpl(BuiltinImplSource::Object { vtable_base }), goal, assumption.to_predicate(tcx), - ) { - Ok(result) => candidates.push(Candidate { - source: CandidateSource::BuiltinImpl(BuiltinImplSource::Object { - vtable_base, - }), - result, - }), - Err(NoSolution) => (), - } + )); }); } } @@ -779,25 +765,20 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { candidates: &mut Vec>, ) { let tcx = self.tcx(); - let result = self.probe_misc_candidate("coherence unknowable").enter(|ecx| { - let trait_ref = goal.predicate.trait_ref(tcx); - let lazily_normalize_ty = |ty| ecx.structurally_normalize_ty(goal.param_env, ty); - match coherence::trait_ref_is_knowable(tcx, trait_ref, lazily_normalize_ty)? { - Ok(()) => Err(NoSolution), - Err(_) => { - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) + candidates.extend(self.probe_trait_candidate(CandidateSource::CoherenceUnknowable).enter( + |ecx| { + let trait_ref = goal.predicate.trait_ref(tcx); + let lazily_normalize_ty = |ty| ecx.structurally_normalize_ty(goal.param_env, ty); + + match coherence::trait_ref_is_knowable(tcx, trait_ref, lazily_normalize_ty)? { + Ok(()) => Err(NoSolution), + Err(_) => { + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) + } } - } - }); - - match result { - Ok(result) => candidates.push(Candidate { - source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), - result, - }), - Err(NoSolution) => {} - } + }, + )) } /// If there's a where-bound for the current goal, do not use any impl candidates @@ -842,6 +823,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { false } CandidateSource::ParamEnv(_) | CandidateSource::AliasBound => true, + CandidateSource::CoherenceUnknowable => bug!("uh oh"), }); } // If it is still ambiguous we instead just force the whole goal @@ -849,7 +831,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // tests/ui/traits/next-solver/env-shadows-impls/ambig-env-no-shadow.rs Certainty::Maybe(cause) => { debug!(?cause, "force ambiguity"); - *candidates = self.forced_ambiguity(cause); + *candidates = self.forced_ambiguity(cause).into_iter().collect(); } } } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 21efce748792..225479fcff34 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -998,19 +998,21 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { if candidate_key.def_id != key.def_id { continue; } - values.extend(self.probe_misc_candidate("opaque type storage").enter(|ecx| { - for (a, b) in std::iter::zip(candidate_key.args, key.args) { - ecx.eq(param_env, a, b)?; - } - ecx.eq(param_env, candidate_ty, ty)?; - ecx.add_item_bounds_for_hidden_type( - candidate_key.def_id.to_def_id(), - candidate_key.args, - param_env, - candidate_ty, - ); - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - })); + values.extend(self.probe(|_| inspect::ProbeKind::OpaqueTypeStorageLookup).enter( + |ecx| { + for (a, b) in std::iter::zip(candidate_key.args, key.args) { + ecx.eq(param_env, a, b)?; + } + ecx.eq(param_env, candidate_ty, ty)?; + ecx.add_item_bounds_for_hidden_type( + candidate_key.def_id.to_def_id(), + candidate_key.args, + param_env, + candidate_ty, + ); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }, + )); } values } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs index 9d59723e4415..ee23f49939b7 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs @@ -1,6 +1,7 @@ use crate::solve::assembly::Candidate; use super::EvalCtxt; +use rustc_infer::traits::BuiltinImplSource; use rustc_middle::traits::{ query::NoSolution, solve::{inspect, CandidateSource, QueryResult}, @@ -75,24 +76,12 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { ProbeCtxt { ecx: self, probe_kind, _result: PhantomData } } - pub(in crate::solve) fn probe_misc_candidate( + pub(in crate::solve) fn probe_builtin_trait_candidate( &mut self, - name: &'static str, - ) -> ProbeCtxt< - '_, - 'a, - 'tcx, - impl FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind<'tcx>, - QueryResult<'tcx>, - > { - ProbeCtxt { - ecx: self, - probe_kind: move |result: &QueryResult<'tcx>| inspect::ProbeKind::MiscCandidate { - name, - result: *result, - }, - _result: PhantomData, - } + source: BuiltinImplSource, + ) -> TraitProbeCtxt<'_, 'a, 'tcx, impl FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind<'tcx>> + { + self.probe_trait_candidate(CandidateSource::BuiltinImpl(source)) } pub(in crate::solve) fn probe_trait_candidate( diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs index 6644d3c77afd..6cce37642c11 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs @@ -107,6 +107,8 @@ impl<'tcx> InferCtxt<'tcx> { Ok(Some(ImplSource::Param(vec![]))) } + (_, CandidateSource::CoherenceUnknowable) => bug!(), + (Certainty::Maybe(_), _) => Ok(None), } }) diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index e918f20577cc..7daf99cb7e56 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -198,7 +198,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { match probe.kind { inspect::ProbeKind::NormalizedSelfTyAssembly | inspect::ProbeKind::UnsizeAssembly - | inspect::ProbeKind::UpcastProjectionCompatibility => (), + | inspect::ProbeKind::UpcastProjectionCompatibility + | inspect::ProbeKind::OpaqueTypeStorageLookup => (), // We add a candidate for the root evaluation if there // is only one way to prove a given goal, e.g. for `WellFormed`. // @@ -218,8 +219,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { }) } } - inspect::ProbeKind::MiscCandidate { name: _, result } - | inspect::ProbeKind::TraitCandidate { source: _, result } => { + inspect::ProbeKind::TraitCandidate { source: _, result } => { candidates.push(InspectCandidate { goal: self, kind: probe.kind, diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index 008927a23402..dab87fffe461 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -8,11 +8,10 @@ use rustc_hir::def_id::DefId; use rustc_hir::LangItem; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::inspect::ProbeKind; +use rustc_infer::traits::solve::MaybeCause; use rustc_infer::traits::specialization_graph::LeafDef; use rustc_infer::traits::Reveal; -use rustc_middle::traits::solve::{ - CandidateSource, CanonicalResponse, Certainty, Goal, QueryResult, -}; +use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal, QueryResult}; use rustc_middle::traits::BuiltinImplSource; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::NormalizesTo; @@ -119,14 +118,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn probe_and_match_goal_against_assumption( ecx: &mut EvalCtxt<'_, 'tcx>, + source: CandidateSource, goal: Goal<'tcx, Self>, assumption: ty::Clause<'tcx>, then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if let Some(projection_pred) = assumption.as_projection_clause() { if projection_pred.projection_def_id() == goal.predicate.def_id() { let tcx = ecx.tcx(); - ecx.probe_misc_candidate("assumption").enter(|ecx| { + ecx.probe_trait_candidate(source).enter(|ecx| { let assumption_projection_pred = ecx.instantiate_binder_with_infer(projection_pred); ecx.eq( @@ -300,14 +300,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_error_guaranteed_candidate( _ecx: &mut EvalCtxt<'_, 'tcx>, _guar: ErrorGuaranteed, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { Err(NoSolution) } fn consider_auto_trait_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { ecx.tcx().dcx().span_delayed_bug( ecx.tcx().def_span(goal.predicate.def_id()), "associated types not allowed on auto traits", @@ -318,35 +318,35 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_trait_alias_candidate( _ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { bug!("trait aliases do not have associated types: {:?}", goal); } fn consider_builtin_sized_candidate( _ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { bug!("`Sized` does not have an associated type: {:?}", goal); } fn consider_builtin_copy_clone_candidate( _ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { bug!("`Copy`/`Clone` does not have an associated type: {:?}", goal); } fn consider_builtin_pointer_like_candidate( _ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { bug!("`PointerLike` does not have an associated type: {:?}", goal); } fn consider_builtin_fn_ptr_trait_candidate( _ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { bug!("`FnPtr` does not have an associated type: {:?}", goal); } @@ -354,7 +354,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, goal_kind: ty::ClosureKind, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { let tcx = ecx.tcx(); let tupled_inputs_and_output = match structural_traits::extract_tupled_inputs_and_output_from_callable( @@ -364,8 +364,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { )? { Some(tupled_inputs_and_output) => tupled_inputs_and_output, None => { - return ecx - .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS); + return ecx.forced_ambiguity(MaybeCause::Ambiguity); } }; let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| { @@ -387,6 +386,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { // (FIXME: technically we only need to check this if the type is a fn ptr...) Self::probe_and_consider_implied_clause( ecx, + CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, pred, [goal.with(tcx, output_is_sized_pred)], @@ -397,7 +397,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, goal_kind: ty::ClosureKind, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { let tcx = ecx.tcx(); let env_region = match goal_kind { @@ -468,6 +468,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { // (FIXME: technically we only need to check this if the type is a fn ptr...) Self::probe_and_consider_implied_clause( ecx, + CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, pred, [goal.with(tcx, output_is_sized_pred)] @@ -479,7 +480,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_builtin_async_fn_kind_helper_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { let [ closure_fn_kind_ty, goal_kind_ty, @@ -494,7 +495,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { // Bail if the upvars haven't been constrained. if tupled_upvars_ty.expect_ty().is_ty_var() { - return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS); + return ecx.forced_ambiguity(MaybeCause::Ambiguity); } let Some(closure_kind) = closure_fn_kind_ty.expect_ty().to_opt_closure_kind() else { @@ -517,25 +518,27 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { borrow_region.expect_region(), ); - ecx.instantiate_normalizes_to_term(goal, upvars_ty.into()); - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { + ecx.instantiate_normalizes_to_term(goal, upvars_ty.into()); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) } fn consider_builtin_tuple_candidate( _ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { bug!("`Tuple` does not have an associated type: {:?}", goal); } fn consider_builtin_pointee_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { let tcx = ecx.tcx(); let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); assert_eq!(metadata_def_id, goal.predicate.def_id()); - ecx.probe_misc_candidate("builtin pointee").enter(|ecx| { + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { let metadata_ty = match goal.predicate.self_ty().kind() { ty::Bool | ty::Char @@ -614,7 +617,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_builtin_future_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { let self_ty = goal.predicate.self_ty(); let ty::Coroutine(def_id, args) = *self_ty.kind() else { return Err(NoSolution); @@ -630,6 +633,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { Self::probe_and_consider_implied_clause( ecx, + CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, ty::ProjectionPredicate { projection_ty: ty::AliasTy::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]), @@ -645,7 +649,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_builtin_iterator_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { let self_ty = goal.predicate.self_ty(); let ty::Coroutine(def_id, args) = *self_ty.kind() else { return Err(NoSolution); @@ -661,6 +665,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { Self::probe_and_consider_implied_clause( ecx, + CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, ty::ProjectionPredicate { projection_ty: ty::AliasTy::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]), @@ -676,14 +681,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_builtin_fused_iterator_candidate( _ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { bug!("`FusedIterator` does not have an associated type: {:?}", goal); } fn consider_builtin_async_iterator_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { let self_ty = goal.predicate.self_ty(); let ty::Coroutine(def_id, args) = *self_ty.kind() else { return Err(NoSolution); @@ -695,7 +700,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { return Err(NoSolution); } - ecx.probe_misc_candidate("builtin AsyncIterator kind").enter(|ecx| { + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { let expected_ty = ecx.next_ty_infer(); // Take `AsyncIterator` and turn it into the corresponding // coroutine yield ty `Poll>`. @@ -719,7 +724,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_builtin_coroutine_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { let self_ty = goal.predicate.self_ty(); let ty::Coroutine(def_id, args) = *self_ty.kind() else { return Err(NoSolution); @@ -744,6 +749,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { Self::probe_and_consider_implied_clause( ecx, + CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, ty::ProjectionPredicate { projection_ty: ty::AliasTy::new( @@ -763,14 +769,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_structural_builtin_unsize_candidates( _ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> Vec<(CanonicalResponse<'tcx>, BuiltinImplSource)> { + ) -> Vec> { bug!("`Unsize` does not have an associated type: {:?}", goal); } fn consider_builtin_discriminant_kind_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { let self_ty = goal.predicate.self_ty(); let discriminant_ty = match *self_ty.kind() { ty::Bool @@ -813,7 +819,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ), }; - ecx.probe_misc_candidate("builtin discriminant kind").enter(|ecx| { + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { ecx.instantiate_normalizes_to_term(goal, discriminant_ty.into()); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) @@ -822,7 +828,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_builtin_async_destruct_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { let self_ty = goal.predicate.self_ty(); let async_destructor_ty = match *self_ty.kind() { ty::Bool @@ -865,7 +871,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ), }; - ecx.probe_misc_candidate("builtin async destruct").enter(|ecx| { + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { ecx.eq(goal.param_env, goal.predicate.term, async_destructor_ty.into()) .expect("expected goal term to be fully unconstrained"); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) @@ -875,14 +881,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_builtin_destruct_candidate( _ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { bug!("`Destruct` does not have an associated type: {:?}", goal); } fn consider_builtin_transmute_candidate( _ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { bug!("`BikeshedIntrinsicFrom` does not have an associated type: {:?}", goal) } } diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 07cdc4fb77a2..c8cb14abb554 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -9,10 +9,9 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def_id::DefId; use rustc_hir::{LangItem, Movability}; use rustc_infer::traits::query::NoSolution; +use rustc_infer::traits::solve::MaybeCause; use rustc_middle::traits::solve::inspect::ProbeKind; -use rustc_middle::traits::solve::{ - CandidateSource, CanonicalResponse, Certainty, Goal, QueryResult, -}; +use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal, QueryResult}; use rustc_middle::traits::{BuiltinImplSource, Reveal}; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt}; @@ -94,21 +93,24 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_error_guaranteed_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, _guar: ErrorGuaranteed, - ) -> QueryResult<'tcx> { - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + ) -> Result, NoSolution> { + // FIXME: don't need to enter a probe here. + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } fn probe_and_match_goal_against_assumption( ecx: &mut EvalCtxt<'_, 'tcx>, + source: CandidateSource, goal: Goal<'tcx, Self>, assumption: ty::Clause<'tcx>, then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if let Some(trait_clause) = assumption.as_trait_clause() { if trait_clause.def_id() == goal.predicate.def_id() && trait_clause.polarity() == goal.predicate.polarity { - ecx.probe_misc_candidate("assumption").enter(|ecx| { + ecx.probe_trait_candidate(source).enter(|ecx| { let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause); ecx.eq( goal.param_env, @@ -128,7 +130,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_auto_trait_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -162,6 +164,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { } ecx.probe_and_evaluate_goal_for_constituent_tys( + CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, structural_traits::instantiate_constituent_tys_for_auto_trait, ) @@ -170,14 +173,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_trait_alias_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } let tcx = ecx.tcx(); - ecx.probe_misc_candidate("trait alias").enter(|ecx| { + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { let nested_obligations = tcx .predicates_of(goal.predicate.def_id()) .instantiate(tcx, goal.predicate.trait_ref.args); @@ -193,12 +196,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_sized_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } ecx.probe_and_evaluate_goal_for_constituent_tys( + CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, structural_traits::instantiate_constituent_tys_for_sized_trait, ) @@ -207,12 +211,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_copy_clone_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } ecx.probe_and_evaluate_goal_for_constituent_tys( + CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, structural_traits::instantiate_constituent_tys_for_copy_clone_trait, ) @@ -221,7 +226,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_pointer_like_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -234,14 +239,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { let key = tcx.erase_regions(goal.param_env.and(goal.predicate.self_ty())); // But if there are inference variables, we have to wait until it's resolved. if key.has_non_region_infer() { - return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS); + return ecx.forced_ambiguity(MaybeCause::Ambiguity); } if let Ok(layout) = tcx.layout_of(key) && layout.layout.is_pointer_like(&tcx.data_layout) { // FIXME: We could make this faster by making a no-constraints response - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } else { Err(NoSolution) } @@ -250,13 +256,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_fn_ptr_trait_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { let self_ty = goal.predicate.self_ty(); match goal.predicate.polarity { // impl FnPtr for FnPtr {} ty::PredicatePolarity::Positive => { if self_ty.is_fn_ptr() { - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) } else { Err(NoSolution) } @@ -266,7 +274,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // If a type is rigid and not a fn ptr, then we know for certain // that it does *not* implement `FnPtr`. if !self_ty.is_fn_ptr() && self_ty.is_known_rigid() { - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) } else { Err(NoSolution) } @@ -278,7 +288,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, goal_kind: ty::ClosureKind, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -292,8 +302,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { )? { Some(a) => a, None => { - return ecx - .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS); + return ecx.forced_ambiguity(MaybeCause::Ambiguity); } }; let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| { @@ -309,6 +318,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // (FIXME: technically we only need to check this if the type is a fn ptr...) Self::probe_and_consider_implied_clause( ecx, + CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, pred, [goal.with(tcx, output_is_sized_pred)], @@ -319,7 +329,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, goal_kind: ty::ClosureKind, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -352,6 +362,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // (FIXME: technically we only need to check this if the type is a fn ptr...) Self::probe_and_consider_implied_clause( ecx, + CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, pred, [goal.with(tcx, output_is_sized_pred)] @@ -363,7 +374,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_async_fn_kind_helper_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { let [closure_fn_kind_ty, goal_kind_ty] = **goal.predicate.trait_ref.args else { bug!(); }; @@ -374,7 +385,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { }; let goal_kind = goal_kind_ty.expect_ty().to_opt_closure_kind().unwrap(); if closure_kind.extends(goal_kind) { - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } else { Err(NoSolution) } @@ -389,13 +401,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_tuple_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } if let ty::Tuple(..) = goal.predicate.self_ty().kind() { - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } else { Err(NoSolution) } @@ -404,18 +417,19 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_pointee_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } fn consider_builtin_future_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -433,13 +447,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // Async coroutine unconditionally implement `Future` // Technically, we need to check that the future output type is Sized, // but that's already proven by the coroutine being WF. - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + // FIXME: use `consider_implied` + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } fn consider_builtin_iterator_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -457,13 +473,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // Gen coroutines unconditionally implement `Iterator` // Technically, we need to check that the iterator output type is Sized, // but that's already proven by the coroutines being WF. - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + // FIXME: use `consider_implied` + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } fn consider_builtin_fused_iterator_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -479,13 +497,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { } // Gen coroutines unconditionally implement `FusedIterator` - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + // FIXME: use `consider_implied` + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } fn consider_builtin_async_iterator_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -503,13 +523,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // Gen coroutines unconditionally implement `Iterator` // Technically, we need to check that the iterator output type is Sized, // but that's already proven by the coroutines being WF. - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + // FIXME: use `consider_implied` + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } fn consider_builtin_coroutine_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -528,6 +550,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { let coroutine = args.as_coroutine(); Self::probe_and_consider_implied_clause( ecx, + CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, ty::TraitRef::new(tcx, goal.predicate.def_id(), [self_ty, coroutine.resume_ty()]) .to_predicate(tcx), @@ -540,31 +563,33 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_discriminant_kind_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } // `DiscriminantKind` is automatically implemented for every type. - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } fn consider_builtin_async_destruct_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } // `AsyncDestruct` is automatically implemented for every type. - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } fn consider_builtin_destruct_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -573,13 +598,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // `Destruct` is automatically implemented for every type in // non-const environments. - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } fn consider_builtin_transmute_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -599,11 +625,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { return Err(NoSolution); }; - let certainty = ecx.is_transmutable( - rustc_transmute::Types { dst: args.type_at(0), src: args.type_at(1) }, - assume, - )?; - ecx.evaluate_added_goals_and_make_canonical_response(certainty) + // FIXME: This actually should destructure the `Result` we get from transmutability and + // register candiates. We probably need to register >1 since we may have an OR of ANDs. + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { + let certainty = ecx.is_transmutable( + rustc_transmute::Types { dst: args.type_at(0), src: args.type_at(1) }, + assume, + )?; + ecx.evaluate_added_goals_and_make_canonical_response(certainty) + }) } /// ```ignore (builtin impl example) @@ -616,20 +646,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_structural_builtin_unsize_candidates( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> Vec<(CanonicalResponse<'tcx>, BuiltinImplSource)> { + ) -> Vec> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return vec![]; } - let misc_candidate = |ecx: &mut EvalCtxt<'_, 'tcx>, certainty| { - ( - ecx.evaluate_added_goals_and_make_canonical_response(certainty).unwrap(), - BuiltinImplSource::Misc, - ) - }; - - let result_to_single = |result, source| match result { - Ok(resp) => vec![(resp, source)], + let result_to_single = |result| match result { + Ok(resp) => vec![resp], Err(NoSolution) => vec![], }; @@ -647,7 +670,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { let goal = goal.with(ecx.tcx(), (a_ty, b_ty)); match (a_ty.kind(), b_ty.kind()) { (ty::Infer(ty::TyVar(..)), ..) => bug!("unexpected infer {a_ty:?} {b_ty:?}"), - (_, ty::Infer(ty::TyVar(..))) => vec![misc_candidate(ecx, Certainty::AMBIGUOUS)], + + (_, ty::Infer(ty::TyVar(..))) => { + result_to_single(ecx.forced_ambiguity(MaybeCause::Ambiguity)) + } // Trait upcasting, or `dyn Trait + Auto + 'a` -> `dyn Trait + 'b`. ( @@ -660,14 +686,12 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // `T` -> `dyn Trait` unsizing. (_, &ty::Dynamic(b_region, b_data, ty::Dyn)) => result_to_single( ecx.consider_builtin_unsize_to_dyn_candidate(goal, b_region, b_data), - BuiltinImplSource::Misc, ), // `[T; N]` -> `[T]` unsizing - (&ty::Array(a_elem_ty, ..), &ty::Slice(b_elem_ty)) => result_to_single( - ecx.consider_builtin_array_unsize(goal, a_elem_ty, b_elem_ty), - BuiltinImplSource::Misc, - ), + (&ty::Array(a_elem_ty, ..), &ty::Slice(b_elem_ty)) => { + result_to_single(ecx.consider_builtin_array_unsize(goal, a_elem_ty, b_elem_ty)) + } // `Struct` -> `Struct` where `T: Unsize` (&ty::Adt(a_def, a_args), &ty::Adt(b_def, b_args)) @@ -675,7 +699,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { { result_to_single( ecx.consider_builtin_struct_unsize(goal, a_def, a_args, b_args), - BuiltinImplSource::Misc, ) } @@ -683,10 +706,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { (&ty::Tuple(a_tys), &ty::Tuple(b_tys)) if a_tys.len() == b_tys.len() && !a_tys.is_empty() => { - result_to_single( - ecx.consider_builtin_tuple_unsize(goal, a_tys, b_tys), - BuiltinImplSource::TupleUnsizing, - ) + result_to_single(ecx.consider_builtin_tuple_unsize(goal, a_tys, b_tys)) } _ => vec![], @@ -712,7 +732,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { a_region: ty::Region<'tcx>, b_data: &'tcx ty::List>, b_region: ty::Region<'tcx>, - ) -> Vec<(CanonicalResponse<'tcx>, BuiltinImplSource)> { + ) -> Vec> { let tcx = self.tcx(); let Goal { predicate: (a_ty, _b_ty), .. } = goal; @@ -720,35 +740,32 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // If the principal def ids match (or are both none), then we're not doing // trait upcasting. We're just removing auto traits (or shortening the lifetime). if a_data.principal_def_id() == b_data.principal_def_id() { - if let Ok(resp) = self.consider_builtin_upcast_to_principal( + responses.extend(self.consider_builtin_upcast_to_principal( goal, + CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), a_data, a_region, b_data, b_region, a_data.principal(), - ) { - responses.push((resp, BuiltinImplSource::Misc)); - } + )); } else if let Some(a_principal) = a_data.principal() { self.walk_vtable( a_principal.with_self_ty(tcx, a_ty), |ecx, new_a_principal, _, vtable_vptr_slot| { - if let Ok(resp) = ecx.probe_misc_candidate("dyn upcast").enter(|ecx| { - ecx.consider_builtin_upcast_to_principal( - goal, - a_data, - a_region, - b_data, - b_region, - Some(new_a_principal.map_bound(|trait_ref| { - ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref) - })), - ) - }) { - responses - .push((resp, BuiltinImplSource::TraitUpcasting { vtable_vptr_slot })); - } + responses.extend(ecx.consider_builtin_upcast_to_principal( + goal, + CandidateSource::BuiltinImpl(BuiltinImplSource::TraitUpcasting { + vtable_vptr_slot, + }), + a_data, + a_region, + b_data, + b_region, + Some(new_a_principal.map_bound(|trait_ref| { + ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref) + })), + )); }, ); } @@ -761,7 +778,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>, b_data: &'tcx ty::List>, b_region: ty::Region<'tcx>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { let tcx = self.tcx(); let Goal { predicate: (a_ty, _), .. } = goal; @@ -770,37 +787,40 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { return Err(NoSolution); } - // Check that the type implements all of the predicates of the trait object. - // (i.e. the principal, all of the associated types match, and any auto traits) - self.add_goals( - GoalSource::ImplWhereBound, - b_data.iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))), - ); - - // The type must be `Sized` to be unsized. - if let Some(sized_def_id) = tcx.lang_items().sized_trait() { - self.add_goal( + self.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { + // Check that the type implements all of the predicates of the trait object. + // (i.e. the principal, all of the associated types match, and any auto traits) + ecx.add_goals( GoalSource::ImplWhereBound, - goal.with(tcx, ty::TraitRef::new(tcx, sized_def_id, [a_ty])), + b_data.iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))), ); - } else { - return Err(NoSolution); - } - // The type must outlive the lifetime of the `dyn` we're unsizing into. - self.add_goal(GoalSource::Misc, goal.with(tcx, ty::OutlivesPredicate(a_ty, b_region))); - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + // The type must be `Sized` to be unsized. + if let Some(sized_def_id) = tcx.lang_items().sized_trait() { + ecx.add_goal( + GoalSource::ImplWhereBound, + goal.with(tcx, ty::TraitRef::new(tcx, sized_def_id, [a_ty])), + ); + } else { + return Err(NoSolution); + } + + // The type must outlive the lifetime of the `dyn` we're unsizing into. + ecx.add_goal(GoalSource::Misc, goal.with(tcx, ty::OutlivesPredicate(a_ty, b_region))); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) } fn consider_builtin_upcast_to_principal( &mut self, goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>, + source: CandidateSource, a_data: &'tcx ty::List>, a_region: ty::Region<'tcx>, b_data: &'tcx ty::List>, b_region: ty::Region<'tcx>, upcast_principal: Option>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { let param_env = goal.param_env; // We may upcast to auto traits that are either explicitly listed in @@ -819,7 +839,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // having any inference side-effects. We process obligations because // unification may initially succeed due to deferred projection equality. let projection_may_match = - |ecx: &mut Self, + |ecx: &mut EvalCtxt<'_, 'tcx>, source_projection: ty::PolyExistentialProjection<'tcx>, target_projection: ty::PolyExistentialProjection<'tcx>| { source_projection.item_def_id() == target_projection.item_def_id() @@ -833,54 +853,60 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { .is_ok() }; - for bound in b_data { - match bound.skip_binder() { - // Check that a's supertrait (upcast_principal) is compatible - // with the target (b_ty). - ty::ExistentialPredicate::Trait(target_principal) => { - self.eq(param_env, upcast_principal.unwrap(), bound.rebind(target_principal))?; - } - // Check that b_ty's projection is satisfied by exactly one of - // a_ty's projections. First, we look through the list to see if - // any match. If not, error. Then, if *more* than one matches, we - // return ambiguity. Otherwise, if exactly one matches, equate - // it with b_ty's projection. - ty::ExistentialPredicate::Projection(target_projection) => { - let target_projection = bound.rebind(target_projection); - let mut matching_projections = - a_data.projection_bounds().filter(|source_projection| { - projection_may_match(self, *source_projection, target_projection) - }); - let Some(source_projection) = matching_projections.next() else { - return Err(NoSolution); - }; - if matching_projections.next().is_some() { - return self.evaluate_added_goals_and_make_canonical_response( - Certainty::AMBIGUOUS, - ); + self.probe_trait_candidate(source).enter(|ecx| { + for bound in b_data { + match bound.skip_binder() { + // Check that a's supertrait (upcast_principal) is compatible + // with the target (b_ty). + ty::ExistentialPredicate::Trait(target_principal) => { + ecx.eq( + param_env, + upcast_principal.unwrap(), + bound.rebind(target_principal), + )?; } - self.eq(param_env, source_projection, target_projection)?; - } - // Check that b_ty's auto traits are present in a_ty's bounds. - ty::ExistentialPredicate::AutoTrait(def_id) => { - if !a_auto_traits.contains(&def_id) { - return Err(NoSolution); + // Check that b_ty's projection is satisfied by exactly one of + // a_ty's projections. First, we look through the list to see if + // any match. If not, error. Then, if *more* than one matches, we + // return ambiguity. Otherwise, if exactly one matches, equate + // it with b_ty's projection. + ty::ExistentialPredicate::Projection(target_projection) => { + let target_projection = bound.rebind(target_projection); + let mut matching_projections = + a_data.projection_bounds().filter(|source_projection| { + projection_may_match(ecx, *source_projection, target_projection) + }); + let Some(source_projection) = matching_projections.next() else { + return Err(NoSolution); + }; + if matching_projections.next().is_some() { + return ecx.evaluate_added_goals_and_make_canonical_response( + Certainty::AMBIGUOUS, + ); + } + ecx.eq(param_env, source_projection, target_projection)?; + } + // Check that b_ty's auto traits are present in a_ty's bounds. + ty::ExistentialPredicate::AutoTrait(def_id) => { + if !a_auto_traits.contains(&def_id) { + return Err(NoSolution); + } } } } - } - // Also require that a_ty's lifetime outlives b_ty's lifetime. - self.add_goal( - GoalSource::ImplWhereBound, - Goal::new( - self.tcx(), - param_env, - ty::Binder::dummy(ty::OutlivesPredicate(a_region, b_region)), - ), - ); + // Also require that a_ty's lifetime outlives b_ty's lifetime. + ecx.add_goal( + GoalSource::ImplWhereBound, + Goal::new( + ecx.tcx(), + param_env, + ty::Binder::dummy(ty::OutlivesPredicate(a_region, b_region)), + ), + ); - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) } /// We have the following builtin impls for arrays: @@ -896,9 +922,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>, a_elem_ty: Ty<'tcx>, b_elem_ty: Ty<'tcx>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { self.eq(goal.param_env, a_elem_ty, b_elem_ty)?; - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + self.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } /// We generate a builtin `Unsize` impls for structs with generic parameters only @@ -920,7 +947,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { def: ty::AdtDef<'tcx>, a_args: ty::GenericArgsRef<'tcx>, b_args: ty::GenericArgsRef<'tcx>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { let tcx = self.tcx(); let Goal { predicate: (_a_ty, b_ty), .. } = goal; @@ -962,7 +989,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { ), ), ); - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + self.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } /// We generate the following builtin impl for tuples of all sizes. @@ -980,7 +1008,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>, a_tys: &'tcx ty::List>, b_tys: &'tcx ty::List>, - ) -> QueryResult<'tcx> { + ) -> Result, NoSolution> { let tcx = self.tcx(); let Goal { predicate: (_a_ty, b_ty), .. } = goal; @@ -1004,7 +1032,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { ), ), ); - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + self.probe_builtin_trait_candidate(BuiltinImplSource::TupleUnsizing) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) } // Return `Some` if there is an impl (built-in or user provided) that may @@ -1014,7 +1043,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { fn disqualify_auto_trait_candidate_due_to_possible_impl( &mut self, goal: Goal<'tcx, TraitPredicate<'tcx>>, - ) -> Option> { + ) -> Option, NoSolution>> { let self_ty = goal.predicate.self_ty(); match *self_ty.kind() { // Stall int and float vars until they are resolved to a concrete @@ -1023,7 +1052,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // we probably don't want to treat an `impl !AutoTrait for i32` as // disqualifying the built-in auto impl for `i64: AutoTrait` either. ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => { - Some(self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)) + Some(self.forced_ambiguity(MaybeCause::Ambiguity)) } // These types cannot be structurally decomposed into constituent @@ -1044,9 +1073,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { { match self.tcx().coroutine_movability(def_id) { Movability::Static => Some(Err(NoSolution)), - Movability::Movable => { - Some(self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) - } + Movability::Movable => Some( + self.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }), + ), } } @@ -1111,13 +1142,14 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// wrapped in one. fn probe_and_evaluate_goal_for_constituent_tys( &mut self, + source: CandidateSource, goal: Goal<'tcx, TraitPredicate<'tcx>>, constituent_tys: impl Fn( &EvalCtxt<'_, 'tcx>, Ty<'tcx>, ) -> Result>>, NoSolution>, - ) -> QueryResult<'tcx> { - self.probe_misc_candidate("constituent tys").enter(|ecx| { + ) -> Result, NoSolution> { + self.probe_trait_candidate(source).enter(|ecx| { ecx.add_goals( GoalSource::ImplWhereBound, constituent_tys(ecx, goal.predicate.self_ty())? diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index a4208cdc3c62..c430da10b0cb 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -1078,9 +1078,8 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> { // Add ambiguity causes for unknowable goals. let mut ambiguity_cause = None; for cand in goal.candidates() { - // FIXME: boiiii, using string comparisions here sure is scuffed. - if let inspect::ProbeKind::MiscCandidate { - name: "coherence unknowable", + if let inspect::ProbeKind::TraitCandidate { + source: CandidateSource::CoherenceUnknowable, result: Ok(_), } = cand.kind() { From 2eb7c8196bbbd0b990f053365f7c934f10963af0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 28 Apr 2024 15:35:35 -0400 Subject: [PATCH 169/279] Only register candidate if it is associated w a shallow certainty --- .../rustc_middle/src/traits/solve/inspect.rs | 4 +- .../src/traits/solve/inspect/format.rs | 4 +- .../src/solve/eval_ctxt/mod.rs | 11 ++-- .../src/solve/inspect/analyse.rs | 55 +++++++------------ 4 files changed, 32 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_middle/src/traits/solve/inspect.rs b/compiler/rustc_middle/src/traits/solve/inspect.rs index 66542431149f..0f3ace2d55d3 100644 --- a/compiler/rustc_middle/src/traits/solve/inspect.rs +++ b/compiler/rustc_middle/src/traits/solve/inspect.rs @@ -150,6 +150,6 @@ pub enum ProbeKind<'tcx> { /// do a probe to find out what projection type(s) may be used to prove that /// the source type upholds all of the target type's object bounds. UpcastProjectionCompatibility, - /// Try to unify an opaque type with an existing - OpaqueTypeStorageLookup, + /// Try to unify an opaque type with an existing key in the storage. + OpaqueTypeStorageLookup { result: QueryResult<'tcx> }, } diff --git a/compiler/rustc_middle/src/traits/solve/inspect/format.rs b/compiler/rustc_middle/src/traits/solve/inspect/format.rs index 91f0880fd208..2d73be387fdc 100644 --- a/compiler/rustc_middle/src/traits/solve/inspect/format.rs +++ b/compiler/rustc_middle/src/traits/solve/inspect/format.rs @@ -112,8 +112,8 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> { ProbeKind::UpcastProjectionCompatibility => { write!(self.f, "PROBING FOR PROJECTION COMPATIBILITY FOR UPCASTING:") } - ProbeKind::OpaqueTypeStorageLookup => { - write!(self.f, "PROBING FOR AN EXISTING OPAQUE:") + ProbeKind::OpaqueTypeStorageLookup { result } => { + write!(self.f, "PROBING FOR AN EXISTING OPAQUE: {result:?}") } ProbeKind::TraitCandidate { source, result } => { write!(self.f, "CANDIDATE {source:?}: {result:?}") diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 225479fcff34..d8fd5c059114 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -998,8 +998,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { if candidate_key.def_id != key.def_id { continue; } - values.extend(self.probe(|_| inspect::ProbeKind::OpaqueTypeStorageLookup).enter( - |ecx| { + values.extend( + self.probe(|result| inspect::ProbeKind::OpaqueTypeStorageLookup { + result: *result, + }) + .enter(|ecx| { for (a, b) in std::iter::zip(candidate_key.args, key.args) { ecx.eq(param_env, a, b)?; } @@ -1011,8 +1014,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { candidate_ty, ); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - }, - )); + }), + ); } values } diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 7daf99cb7e56..2d58111e8038 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -45,7 +45,7 @@ pub struct InspectCandidate<'a, 'tcx> { nested_goals: Vec>>>, final_state: inspect::CanonicalState<'tcx, ()>, result: QueryResult<'tcx>, - candidate_certainty: Option, + shallow_certainty: Certainty, } impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { @@ -59,15 +59,14 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { /// Certainty passed into `evaluate_added_goals_and_make_canonical_response`. /// - /// If this certainty is `Some(Yes)`, then we must be confident that the candidate + /// If this certainty is `Yes`, then we must be confident that the candidate /// must hold iff it's nested goals hold. This is not true if the certainty is - /// `Some(Maybe)`, which suggests we forced ambiguity instead, or if it is `None`, - /// which suggests we may have not assembled any candidates at all. + /// `Maybe(..)`, which suggests we forced ambiguity instead. /// - /// This is *not* the certainty of the candidate's nested evaluation, which can be - /// accessed with [`Self::result`] instead. - pub fn candidate_certainty(&self) -> Option { - self.candidate_certainty + /// This is *not* the certainty of the candidate's full nested evaluation, which + /// can be accessed with [`Self::result`] instead. + pub fn shallow_certainty(&self) -> Certainty { + self.shallow_certainty } /// Visit all nested goals of this candidate without rolling @@ -174,9 +173,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { nested_goals: &mut Vec>>>, probe: &inspect::Probe<'tcx>, ) { - let mut candidate_certainty = None; - let num_candidates = candidates.len(); - + let mut shallow_certainty = None; for step in &probe.steps { match step { &inspect::ProbeStep::AddGoal(_source, goal) => nested_goals.push(goal), @@ -188,8 +185,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { self.candidates_recur(candidates, nested_goals, probe); nested_goals.truncate(num_goals); } - inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty } => { - assert_eq!(candidate_certainty.replace(*shallow_certainty), None); + inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => { + assert_eq!(shallow_certainty.replace(*c), None); } inspect::ProbeStep::EvaluateGoals(_) => (), } @@ -198,37 +195,27 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { match probe.kind { inspect::ProbeKind::NormalizedSelfTyAssembly | inspect::ProbeKind::UnsizeAssembly - | inspect::ProbeKind::UpcastProjectionCompatibility - | inspect::ProbeKind::OpaqueTypeStorageLookup => (), - // We add a candidate for the root evaluation if there + | inspect::ProbeKind::UpcastProjectionCompatibility => (), + + // We add a candidate even for the root evaluation if there // is only one way to prove a given goal, e.g. for `WellFormed`. - // - // FIXME: This is currently wrong if we don't even try any - // candidates, e.g. for a trait goal, as in this case `candidates` is - // actually supposed to be empty. inspect::ProbeKind::Root { result } - | inspect::ProbeKind::TryNormalizeNonRigid { result } => { - if candidates.len() == num_candidates { + | inspect::ProbeKind::TryNormalizeNonRigid { result } + | inspect::ProbeKind::TraitCandidate { source: _, result } + | inspect::ProbeKind::OpaqueTypeStorageLookup { result } => { + // We only add a candidate if `shallow_certainty` was set, which means + // that we ended up calling `evaluate_added_goals_and_make_canonical_response`. + if let Some(shallow_certainty) = shallow_certainty { candidates.push(InspectCandidate { goal: self, kind: probe.kind, nested_goals: nested_goals.clone(), final_state: probe.final_state, result, - candidate_certainty, - }) + shallow_certainty, + }); } } - inspect::ProbeKind::TraitCandidate { source: _, result } => { - candidates.push(InspectCandidate { - goal: self, - kind: probe.kind, - nested_goals: nested_goals.clone(), - final_state: probe.final_state, - result, - candidate_certainty, - }); - } } } From f0beaedf832c574042bb8ec1957e462b97373758 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Mon, 29 Apr 2024 17:27:40 +0200 Subject: [PATCH 170/279] suppress `readonly_write_lock` for underscore-prefixed bindings --- clippy_lints/src/methods/readonly_write_lock.rs | 7 ++++++- tests/ui/readonly_write_lock.fixed | 4 ++++ tests/ui/readonly_write_lock.rs | 4 ++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/methods/readonly_write_lock.rs b/clippy_lints/src/methods/readonly_write_lock.rs index 9b0180d93699..774aaec1afda 100644 --- a/clippy_lints/src/methods/readonly_write_lock.rs +++ b/clippy_lints/src/methods/readonly_write_lock.rs @@ -4,7 +4,7 @@ use clippy_utils::mir::{enclosing_mir, visit_local_usage}; use clippy_utils::source::snippet; use clippy_utils::ty::is_type_diagnostic_item; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind, Node}; +use rustc_hir::{Expr, ExprKind, Node, PatKind}; use rustc_lint::LateContext; use rustc_middle::mir::{Location, START_BLOCK}; use rustc_span::sym; @@ -25,6 +25,11 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, receiver && is_unwrap_call(cx, unwrap_call_expr) && let parent = cx.tcx.parent_hir_node(unwrap_call_expr.hir_id) && let Node::LetStmt(local) = parent + && let PatKind::Binding(.., ident, _) = local.pat.kind + // if the binding is prefixed with `_`, it typically means + // that this guard only exists to protect a section of code + // rather than the contained data + && !ident.as_str().starts_with('_') && let Some(mir) = enclosing_mir(cx.tcx, expr.hir_id) && let Some((local, _)) = mir .local_decls diff --git a/tests/ui/readonly_write_lock.fixed b/tests/ui/readonly_write_lock.fixed index 76f4a43ae530..4db13482ac78 100644 --- a/tests/ui/readonly_write_lock.fixed +++ b/tests/ui/readonly_write_lock.fixed @@ -43,3 +43,7 @@ fn main() { *writer1 = *writer2; } } + +fn issue12733(rw: &RwLock<()>) { + let _write_guard = rw.write().unwrap(); +} diff --git a/tests/ui/readonly_write_lock.rs b/tests/ui/readonly_write_lock.rs index 3d1d3855fe12..66ba1b2d6969 100644 --- a/tests/ui/readonly_write_lock.rs +++ b/tests/ui/readonly_write_lock.rs @@ -43,3 +43,7 @@ fn main() { *writer1 = *writer2; } } + +fn issue12733(rw: &RwLock<()>) { + let _write_guard = rw.write().unwrap(); +} From f06e0f783793ab5592b6799876d9329b1490bc30 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 29 Apr 2024 11:27:14 -0300 Subject: [PATCH 171/279] Add StaticForeignItem and use it on ForeignItemKind --- compiler/rustc_ast/src/ast.rs | 43 ++++++++++++++++--- compiler/rustc_ast/src/mut_visit.rs | 2 +- compiler/rustc_ast/src/visit.rs | 2 +- compiler/rustc_ast_lowering/src/item.rs | 8 ++-- .../rustc_ast_passes/src/ast_validation.rs | 4 +- .../rustc_ast_pretty/src/pprust/state/item.rs | 20 +++++---- compiler/rustc_parse/src/parser/item.rs | 6 ++- compiler/rustc_resolve/src/def_collector.rs | 2 +- .../clippy/clippy_utils/src/ast_utils.rs | 13 +++++- src/tools/rustfmt/src/items.rs | 6 +-- tests/ui/stats/hir-stats.stderr | 20 ++++----- 11 files changed, 86 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index af246e313718..f24e2a22c073 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3126,6 +3126,35 @@ pub struct StaticItem { pub expr: Option>, } +/// A static item in `extern` block. +// This struct is identical to StaticItem for now but it's going to have a safety attribute. +#[derive(Clone, Encodable, Decodable, Debug)] +pub struct StaticForeignItem { + pub ty: P, + pub mutability: Mutability, + pub expr: Option>, +} + +impl From for StaticForeignItem { + fn from(static_item: StaticItem) -> StaticForeignItem { + StaticForeignItem { + ty: static_item.ty, + mutability: static_item.mutability, + expr: static_item.expr, + } + } +} + +impl From for StaticItem { + fn from(static_item: StaticForeignItem) -> StaticItem { + StaticItem { + ty: static_item.ty, + mutability: static_item.mutability, + expr: static_item.expr, + } + } +} + #[derive(Clone, Encodable, Decodable, Debug)] pub struct ConstItem { pub defaultness: Defaultness, @@ -3329,7 +3358,7 @@ impl TryFrom for AssocItemKind { #[derive(Clone, Encodable, Decodable, Debug)] pub enum ForeignItemKind { /// A foreign static item (`static FOO: u8`). - Static(P, Mutability, Option>), + Static(Box), /// An foreign function. Fn(Box), /// An foreign type. @@ -3341,8 +3370,8 @@ pub enum ForeignItemKind { impl From for ItemKind { fn from(foreign_item_kind: ForeignItemKind) -> ItemKind { match foreign_item_kind { - ForeignItemKind::Static(a, b, c) => { - ItemKind::Static(StaticItem { ty: a, mutability: b, expr: c }.into()) + ForeignItemKind::Static(box static_foreign_item) => { + ItemKind::Static(Box::new(static_foreign_item.into())) } ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind), ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind), @@ -3356,8 +3385,8 @@ impl TryFrom for ForeignItemKind { fn try_from(item_kind: ItemKind) -> Result { Ok(match item_kind { - ItemKind::Static(box StaticItem { ty: a, mutability: b, expr: c }) => { - ForeignItemKind::Static(a, b, c) + ItemKind::Static(box static_item) => { + ForeignItemKind::Static(Box::new(static_item.into())) } ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind), ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind), @@ -3382,8 +3411,8 @@ mod size_asserts { static_assert_size!(Expr, 72); static_assert_size!(ExprKind, 40); static_assert_size!(Fn, 160); - static_assert_size!(ForeignItem, 96); - static_assert_size!(ForeignItemKind, 24); + static_assert_size!(ForeignItem, 88); + static_assert_size!(ForeignItemKind, 16); static_assert_size!(GenericArg, 24); static_assert_size!(GenericBound, 88); static_assert_size!(Generics, 40); diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index fc445600e77b..4d28ef56df17 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1261,7 +1261,7 @@ pub fn noop_flat_map_item( impl NoopVisitItemKind for ForeignItemKind { fn noop_visit(&mut self, visitor: &mut impl MutVisitor) { match self { - ForeignItemKind::Static(ty, _, expr) => { + ForeignItemKind::Static(box StaticForeignItem { ty, mutability: _, expr }) => { visitor.visit_ty(ty); visit_opt(expr, |expr| visitor.visit_expr(expr)); } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index a0ada9a7788d..1d8fd63e4592 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -642,7 +642,7 @@ impl WalkItemKind for ForeignItemKind { ) -> V::Result { let &Item { id, span, ident, ref vis, .. } = item; match self { - ForeignItemKind::Static(ty, _, expr) => { + ForeignItemKind::Static(box StaticForeignItem { ty, mutability: _, expr }) => { try_visit!(visitor.visit_ty(ty)); visit_opt!(visitor, visit_expr, expr); } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index dcce54d66c2d..ccbc44bff578 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -662,10 +662,10 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ForeignItemKind::Fn(fn_dec, fn_args, generics) } - ForeignItemKind::Static(t, m, _) => { - let ty = - self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy)); - hir::ForeignItemKind::Static(ty, *m) + ForeignItemKind::Static(box StaticForeignItem { ty, mutability, expr: _ }) => { + let ty = self + .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy)); + hir::ForeignItemKind::Static(ty, *mutability) } ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type, ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"), diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 1fb410253d1e..1eefad2af4dc 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1185,8 +1185,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_foreign_ty_genericless(generics, where_clauses); self.check_foreign_item_ascii_only(fi.ident); } - ForeignItemKind::Static(_, _, body) => { - self.check_foreign_kind_bodyless(fi.ident, "static", body.as_ref().map(|b| b.span)); + ForeignItemKind::Static(box StaticForeignItem { ty: _, mutability: _, expr }) => { + self.check_foreign_kind_bodyless(fi.ident, "static", expr.as_ref().map(|b| b.span)); self.check_foreign_item_ascii_only(fi.ident); } ForeignItemKind::MacCall(..) => {} diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 10886aace53f..b90182c2b3e6 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -30,15 +30,17 @@ impl<'a> State<'a> { ast::ForeignItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => { self.print_fn_full(sig, ident, generics, vis, *defaultness, body.as_deref(), attrs); } - ast::ForeignItemKind::Static(ty, mutbl, body) => self.print_item_const( - ident, - Some(*mutbl), - &ast::Generics::default(), - ty, - body.as_deref(), - vis, - ast::Defaultness::Final, - ), + ast::ForeignItemKind::Static(box ast::StaticForeignItem { ty, mutability, expr }) => { + self.print_item_const( + ident, + Some(*mutability), + &ast::Generics::default(), + ty, + expr.as_deref(), + vis, + ast::Defaultness::Final, + ) + } ast::ForeignItemKind::TyAlias(box ast::TyAlias { defaultness, generics, diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index ed51710564a4..848277c4611e 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1191,7 +1191,11 @@ impl<'a> Parser<'a> { ident_span: ident.span, const_span, }); - ForeignItemKind::Static(ty, Mutability::Not, expr) + ForeignItemKind::Static(Box::new(StaticForeignItem { + ty, + mutability: Mutability::Not, + expr, + })) } _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"), }, diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index d4d999f6f9ce..a27a6bceda33 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -209,7 +209,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { fn visit_foreign_item(&mut self, fi: &'a ForeignItem) { let def_kind = match fi.kind { - ForeignItemKind::Static(_, mutability, _) => { + ForeignItemKind::Static(box StaticForeignItem { ty: _, mutability, expr: _ }) => { DefKind::Static { mutability, nested: false } } ForeignItemKind::Fn(_) => DefKind::Fn, diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 0395eb1449b4..529d20126b22 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -446,7 +446,18 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool { use ForeignItemKind::*; match (l, r) { - (Static(lt, lm, le), Static(rt, rm, re)) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re), + ( + Static(box StaticForeignItem { + ty: lt, + mutability: lm, + expr: le, + }), + Static(box StaticForeignItem { + ty: rt, + mutability: rm, + expr: re, + }), + ) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re), ( Fn(box ast::Fn { defaultness: ld, diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index f6f51fbd8eaf..e196d1817f34 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -3325,11 +3325,11 @@ impl Rewrite for ast::ForeignItem { .map(|(s, _, _)| format!("{};", s)) } } - ast::ForeignItemKind::Static(ref ty, mutability, _) => { + ast::ForeignItemKind::Static(ref static_foreign_item) => { // FIXME(#21): we're dropping potential comments in between the // function kw here. let vis = format_visibility(context, &self.vis); - let mut_str = format_mutability(mutability); + let mut_str = format_mutability(static_foreign_item.mutability); let prefix = format!( "{}static {}{}:", vis, @@ -3340,7 +3340,7 @@ impl Rewrite for ast::ForeignItem { rewrite_assign_rhs( context, prefix, - &**ty, + &static_foreign_item.ty, &RhsAssignKind::Ty, shape.sub_width(1)?, ) diff --git a/tests/ui/stats/hir-stats.stderr b/tests/ui/stats/hir-stats.stderr index dc24833c267c..1a67c9438449 100644 --- a/tests/ui/stats/hir-stats.stderr +++ b/tests/ui/stats/hir-stats.stderr @@ -11,15 +11,15 @@ ast-stats-1 Attribute 64 ( 1.0%) 2 32 ast-stats-1 - Normal 32 ( 0.5%) 1 ast-stats-1 - DocComment 32 ( 0.5%) 1 ast-stats-1 Local 80 ( 1.2%) 1 80 -ast-stats-1 Arm 96 ( 1.4%) 2 48 -ast-stats-1 ForeignItem 96 ( 1.4%) 1 96 -ast-stats-1 - Fn 96 ( 1.4%) 1 +ast-stats-1 ForeignItem 88 ( 1.3%) 1 88 +ast-stats-1 - Fn 88 ( 1.3%) 1 +ast-stats-1 Arm 96 ( 1.5%) 2 48 ast-stats-1 FnDecl 120 ( 1.8%) 5 24 ast-stats-1 FieldDef 160 ( 2.4%) 2 80 ast-stats-1 Stmt 160 ( 2.4%) 5 32 ast-stats-1 - Let 32 ( 0.5%) 1 ast-stats-1 - MacCall 32 ( 0.5%) 1 -ast-stats-1 - Expr 96 ( 1.4%) 3 +ast-stats-1 - Expr 96 ( 1.5%) 3 ast-stats-1 Param 160 ( 2.4%) 4 40 ast-stats-1 Block 192 ( 2.9%) 6 32 ast-stats-1 Variant 208 ( 3.1%) 2 104 @@ -28,7 +28,7 @@ ast-stats-1 - Trait 352 ( 5.3%) 4 ast-stats-1 AssocItem 352 ( 5.3%) 4 88 ast-stats-1 - Type 176 ( 2.7%) 2 ast-stats-1 - Fn 176 ( 2.7%) 2 -ast-stats-1 GenericParam 480 ( 7.2%) 5 96 +ast-stats-1 GenericParam 480 ( 7.3%) 5 96 ast-stats-1 Pat 504 ( 7.6%) 7 72 ast-stats-1 - Struct 72 ( 1.1%) 1 ast-stats-1 - Wild 72 ( 1.1%) 1 @@ -53,7 +53,7 @@ ast-stats-1 - Impl 136 ( 2.1%) 1 ast-stats-1 - Fn 272 ( 4.1%) 2 ast-stats-1 - Use 408 ( 6.2%) 3 ast-stats-1 ---------------------------------------------------------------- -ast-stats-1 Total 6_624 +ast-stats-1 Total 6_616 ast-stats-1 ast-stats-2 POST EXPANSION AST STATS ast-stats-2 Name Accumulated Size Count Item Size @@ -65,9 +65,9 @@ ast-stats-2 ExprField 48 ( 0.7%) 1 48 ast-stats-2 WherePredicate 56 ( 0.8%) 1 56 ast-stats-2 - BoundPredicate 56 ( 0.8%) 1 ast-stats-2 Local 80 ( 1.1%) 1 80 +ast-stats-2 ForeignItem 88 ( 1.2%) 1 88 +ast-stats-2 - Fn 88 ( 1.2%) 1 ast-stats-2 Arm 96 ( 1.3%) 2 48 -ast-stats-2 ForeignItem 96 ( 1.3%) 1 96 -ast-stats-2 - Fn 96 ( 1.3%) 1 ast-stats-2 InlineAsm 120 ( 1.7%) 1 120 ast-stats-2 FnDecl 120 ( 1.7%) 5 24 ast-stats-2 Attribute 128 ( 1.8%) 4 32 @@ -86,7 +86,7 @@ ast-stats-2 - Trait 352 ( 4.9%) 4 ast-stats-2 AssocItem 352 ( 4.9%) 4 88 ast-stats-2 - Type 176 ( 2.4%) 2 ast-stats-2 - Fn 176 ( 2.4%) 2 -ast-stats-2 GenericParam 480 ( 6.6%) 5 96 +ast-stats-2 GenericParam 480 ( 6.7%) 5 96 ast-stats-2 Pat 504 ( 7.0%) 7 72 ast-stats-2 - Struct 72 ( 1.0%) 1 ast-stats-2 - Wild 72 ( 1.0%) 1 @@ -113,7 +113,7 @@ ast-stats-2 - Impl 136 ( 1.9%) 1 ast-stats-2 - Fn 272 ( 3.8%) 2 ast-stats-2 - Use 544 ( 7.5%) 4 ast-stats-2 ---------------------------------------------------------------- -ast-stats-2 Total 7_224 +ast-stats-2 Total 7_216 ast-stats-2 hir-stats HIR STATS hir-stats Name Accumulated Size Count Item Size From 9276ce1cf3db6045678fa04e9dc3f58bec923c4d Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 29 Apr 2024 11:27:14 -0300 Subject: [PATCH 172/279] Add StaticForeignItem and use it on ForeignItemKind --- clippy_utils/src/ast_utils.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/clippy_utils/src/ast_utils.rs b/clippy_utils/src/ast_utils.rs index 0395eb1449b4..529d20126b22 100644 --- a/clippy_utils/src/ast_utils.rs +++ b/clippy_utils/src/ast_utils.rs @@ -446,7 +446,18 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool { use ForeignItemKind::*; match (l, r) { - (Static(lt, lm, le), Static(rt, rm, re)) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re), + ( + Static(box StaticForeignItem { + ty: lt, + mutability: lm, + expr: le, + }), + Static(box StaticForeignItem { + ty: rt, + mutability: rm, + expr: re, + }), + ) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re), ( Fn(box ast::Fn { defaultness: ld, From 8cea4f3e1e9892a39affd9d1fbfcf94aba11fae2 Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Mon, 29 Apr 2024 17:31:49 +0100 Subject: [PATCH 173/279] arm target docs: small wording fixes --- src/doc/rustc/src/platform-support/arm-none-eabi.md | 2 +- src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc/src/platform-support/arm-none-eabi.md b/src/doc/rustc/src/platform-support/arm-none-eabi.md index 64ae60172380..e7ffc23d2800 100644 --- a/src/doc/rustc/src/platform-support/arm-none-eabi.md +++ b/src/doc/rustc/src/platform-support/arm-none-eabi.md @@ -64,7 +64,7 @@ instructions. It is possible to tell Rust (or LLVM) that you have a specific model of Arm processor, using the [`-C target-cpu`][target-cpu] option. You can also control whether Rust (or LLVM) will include instructions that target optional hardware -features, e.g. hardware floating point, or vector maths operations, using [`-C +features, e.g. hardware floating-point, or Advanced SIMD operations, using [`-C target-feature`][target-feature]. It is important to note that selecting a *target-cpu* will typically enable diff --git a/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md index 9733ce0e0aac..c63620067acf 100644 --- a/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md @@ -14,7 +14,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all This target uses the soft-float ABI: functions which take `f32` or `f64` as arguments will have those values packed into integer registers. This is the -only option because there is no FPU support in [ARMv6-M]. +only option because there is no FPU support in [ARMv8-M] Baseline. [t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture [ARMv8-M]: https://developer.arm.com/documentation/ddi0553/latest/ From 982a58e900783a68f6a9b6bfea33f46b7be68386 Mon Sep 17 00:00:00 2001 From: David Koloski Date: Mon, 29 Apr 2024 17:00:03 +0000 Subject: [PATCH 174/279] Fix Fuchsia build broken by #124210 Fuchsia doesn't support dirfd although we have a symbol stubbed for it. --- library/std/src/sys/pal/unix/fs.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 5987996a3f16..f8fdc6369cdf 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -894,6 +894,7 @@ impl Drop for Dir { target_os = "vita", target_os = "hurd", target_os = "espidf", + target_os = "fuchsia", )))] { let fd = unsafe { libc::dirfd(self.0) }; From b1fa2842b10308b1ac3d482cef2f6ec316b2e98f Mon Sep 17 00:00:00 2001 From: xFrednet Date: Mon, 29 Apr 2024 21:26:14 +0200 Subject: [PATCH 175/279] Update version attribute for 1.78 lints --- clippy_lints/src/assigning_clones.rs | 2 +- clippy_lints/src/cargo/mod.rs | 2 +- clippy_lints/src/casts/mod.rs | 2 +- clippy_lints/src/methods/mod.rs | 4 ++-- clippy_lints/src/multiple_bound_locations.rs | 2 +- clippy_lints/src/to_string_trait_impl.rs | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/assigning_clones.rs b/clippy_lints/src/assigning_clones.rs index d88ca84fb97d..f0dafb1ae0d5 100644 --- a/clippy_lints/src/assigning_clones.rs +++ b/clippy_lints/src/assigning_clones.rs @@ -45,7 +45,7 @@ declare_clippy_lint! { /// a.clone_from(&b); /// } /// ``` - #[clippy::version = "1.77.0"] + #[clippy::version = "1.78.0"] pub ASSIGNING_CLONES, perf, "assigning the result of cloning may be inefficient" diff --git a/clippy_lints/src/cargo/mod.rs b/clippy_lints/src/cargo/mod.rs index ca7fa4e5a410..593bc6c81ee8 100644 --- a/clippy_lints/src/cargo/mod.rs +++ b/clippy_lints/src/cargo/mod.rs @@ -197,7 +197,7 @@ declare_clippy_lint! { /// pedantic = { level = "warn", priority = -1 } /// similar_names = "allow" /// ``` - #[clippy::version = "1.76.0"] + #[clippy::version = "1.78.0"] pub LINT_GROUPS_PRIORITY, correctness, "a lint group in `Cargo.toml` at the same priority as a lint" diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index d14898a8196c..bd2c96f01f6f 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -708,7 +708,7 @@ declare_clippy_lint! { /// let a_ref = &1; /// let a_ptr = std::ptr::from_ref(a_ref); /// ``` - #[clippy::version = "1.77.0"] + #[clippy::version = "1.78.0"] pub REF_AS_PTR, pedantic, "using `as` to cast a reference to pointer" diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 16e508bf4e1d..63545d6c5035 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -3993,7 +3993,7 @@ declare_clippy_lint! { /// let x: Result = Ok(0); /// let y = x.unwrap_or_else(|err| handle_error(err)); /// ``` - #[clippy::version = "1.77.0"] + #[clippy::version = "1.78.0"] pub UNNECESSARY_RESULT_MAP_OR_ELSE, suspicious, "making no use of the \"map closure\" when calling `.map_or_else(|err| handle_error(err), |n| n)`" @@ -4027,7 +4027,7 @@ declare_clippy_lint! { /// needs_cstr(c"Hello"); /// unsafe { libc::puts(c"World".as_ptr()) } /// ``` - #[clippy::version = "1.76.0"] + #[clippy::version = "1.78.0"] pub MANUAL_C_STR_LITERALS, pedantic, r#"creating a `CStr` through functions when `c""` literals can be used"# diff --git a/clippy_lints/src/multiple_bound_locations.rs b/clippy_lints/src/multiple_bound_locations.rs index 191b32408efe..d608f3bf7b4d 100644 --- a/clippy_lints/src/multiple_bound_locations.rs +++ b/clippy_lints/src/multiple_bound_locations.rs @@ -29,7 +29,7 @@ declare_clippy_lint! { /// F: Sized + std::fmt::Debug, /// {} /// ``` - #[clippy::version = "1.77.0"] + #[clippy::version = "1.78.0"] pub MULTIPLE_BOUND_LOCATIONS, suspicious, "defining generic bounds in multiple locations" diff --git a/clippy_lints/src/to_string_trait_impl.rs b/clippy_lints/src/to_string_trait_impl.rs index 59ae185c9de7..0361836cdec7 100644 --- a/clippy_lints/src/to_string_trait_impl.rs +++ b/clippy_lints/src/to_string_trait_impl.rs @@ -38,7 +38,7 @@ declare_clippy_lint! { /// } /// } /// ``` - #[clippy::version = "1.77.0"] + #[clippy::version = "1.78.0"] pub TO_STRING_TRAIT_IMPL, style, "check for direct implementations of `ToString`" From 23341500a619b61fab3bae82c01d18e6407def0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 25 Apr 2024 11:04:49 +0200 Subject: [PATCH 176/279] Unify outcome jobs --- .github/workflows/ci.yml | 40 ++++++++---------------------------- src/ci/github-actions/ci.yml | 37 ++++++++++++++++----------------- 2 files changed, 26 insertions(+), 51 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d691b72488b2..cfcbb8656b1a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -152,49 +152,25 @@ jobs: AWS_ACCESS_KEY_ID: "${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }}" AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }}" if: "success() && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')" - try-success: - needs: - - job - if: "success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'" - steps: - - name: mark the job as a success - run: exit 0 - shell: bash + outcome: name: bors build finished runs-on: ubuntu-latest - try-failure: needs: - job - if: "!success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'" - steps: - - name: mark the job as a failure - run: exit 1 - shell: bash - name: bors build finished - runs-on: ubuntu-latest - auto-success: - needs: - - job - if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" + if: "!cancelled() && github.event_name == 'push'" steps: - name: checkout the source code uses: actions/checkout@v4 with: fetch-depth: 2 + - name: calculate the correct exit status + id: status + run: "jq --exit-status 'all(.result == \"success\" or .result == \"skipped\")' <<< '${{ toJson(needs) }}'\necho \"status=$?\" >> $GITHUB_OUTPUT\n" - name: publish toolstate run: src/ci/publish_toolstate.sh shell: bash + if: "steps.outputs.status == 0 && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" env: TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}" - name: bors build finished - runs-on: ubuntu-latest - auto-failure: - needs: - - job - if: "!success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" - steps: - - name: mark the job as a failure - run: exit 1 - shell: bash - name: bors build finished - runs-on: ubuntu-latest + - name: set the correct exit status + run: "exit ${{ steps.outputs.status == 0 }}" diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 95d2225a6b1c..4ca7b52bc02d 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -270,33 +270,32 @@ jobs: # erroring about invalid credentials instead. if: success() && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1') - # These jobs don't actually test anything, but they're used to tell bors the - # build completed, as there is no practical way to detect when a workflow is - # successful listening to webhooks only. - try-success: + # This job isused to tell bors the final status of the build, as there is no practical way to detect + # when a workflow is successful listening to webhooks only in our current bors implementation (homu). + outcome: + name: bors build finished + runs-on: ubuntu-latest needs: [ job ] - if: "success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'" - <<: *base-success-job - try-failure: - needs: [ job ] - if: "!success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'" - <<: *base-failure-job - auto-success: - needs: [ job ] - if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" - <<: *base-outcome-job + # !cancelled() executes the job regardless of whether the previous jobs passed or failed + if: "!cancelled() && github.event_name == 'push'" steps: - name: checkout the source code uses: actions/checkout@v4 with: fetch-depth: 2 + # Calculate the exit status of the whole CI workflow (0 if all dependent jobs were either successful + # or skipped, otherwise 1). + - name: calculate the correct exit status + id: status + run: | + jq --exit-status 'all(.result == "success" or .result == "skipped")' <<< '${{ toJson(needs) }}' + echo "status=$?" >> $GITHUB_OUTPUT + # Publish the toolstate if an auto build succeeds (just before push to master) - name: publish toolstate run: src/ci/publish_toolstate.sh shell: bash + if: steps.outputs.status == 0 && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust' env: TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }} - - auto-failure: - needs: [ job ] - if: "!success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" - <<: *base-failure-job + - name: set the correct exit status + run: exit ${{ steps.outputs.status }} From 1ca92c085788f68ff9b23cf597da5c62924e3f37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 29 Apr 2024 21:32:35 +0200 Subject: [PATCH 177/279] Replace dynamically generated `ci.yml` file with the original template --- .github/workflows/ci.yml | 172 ++++++++++++++------ src/ci/github-actions/ci.yml | 301 ----------------------------------- 2 files changed, 122 insertions(+), 351 deletions(-) delete mode 100644 src/ci/github-actions/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cfcbb8656b1a..6fdc8d4d72dd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,21 +1,14 @@ -############################################################# -# WARNING: automatically generated file, DO NOT CHANGE! # -############################################################# +# This file defines our primary CI workflow that runs on pull requests +# and also on pushes to special branches (auto, try). +# +# The actual definition of the executed jobs is calculated by a Python +# script located at src/ci/github-actions/calculate-job-matrix.py, which +# uses job definition data from src/ci/github-actions/jobs.yml. +# You should primarily modify the `jobs.yml` file if you want to modify +# what jobs are executed in CI. -# This file was automatically generated by the expand-yaml-anchors tool. The -# source file that generated this one is: -# -# src/ci/github-actions/ci.yml -# -# Once you make changes to that file you need to run: -# -# ./x.py run src/tools/expand-yaml-anchors/ -# -# The CI build will fail if the tool is not run after changes to this file. - ---- name: CI -"on": +on: push: branches: - auto @@ -25,23 +18,35 @@ name: CI pull_request: branches: - "**" + permissions: contents: read packages: write + defaults: run: + # On Linux, macOS, and Windows, use the system-provided bash as the default + # shell. (This should only make a difference on Windows, where the default + # shell is PowerShell.) shell: bash + concurrency: - group: "${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }}" + # For a given workflow, if we push to the same branch, cancel all previous builds on that branch. + # We add an exception for try builds (try branch) and unrolled rollup builds (try-perf), which + # are all triggered on the same branch, but which should be able to run concurrently. + group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }} cancel-in-progress: true env: TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate" jobs: + # The job matrix for `calculate_matrix` is defined in src/ci/github-actions/jobs.yml. + # It calculates which jobs should be executed, based on the data of the ${{ github }} context. + # If you want to modify CI jobs, take a look at src/ci/github-actions/jobs.yml. calculate_matrix: name: Calculate job matrix runs-on: ubuntu-latest outputs: - jobs: "${{ steps.jobs.outputs.jobs }}" + jobs: ${{ steps.jobs.outputs.jobs }} steps: - name: Checkout the source code uses: actions/checkout@v4 @@ -49,128 +54,195 @@ jobs: run: python3 src/ci/github-actions/calculate-job-matrix.py >> $GITHUB_OUTPUT id: jobs job: - name: "${{ matrix.name }}" - needs: - - calculate_matrix + name: ${{ matrix.name }} + needs: [ calculate_matrix ] runs-on: "${{ matrix.os }}" defaults: run: - shell: "${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}" + shell: ${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }} timeout-minutes: 600 env: - CI_JOB_NAME: "${{ matrix.image }}" + CI_JOB_NAME: ${{ matrix.image }} CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}" - DOCKER_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + # commit of PR sha or commit sha. `GITHUB_SHA` is not accurate for PRs. + HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} + DOCKER_TOKEN: ${{ secrets.GITHUB_TOKEN }} SCCACHE_BUCKET: rust-lang-ci-sccache2 CACHE_DOMAIN: ci-caches.rust-lang.org - continue-on-error: "${{ matrix.continue_on_error || false }}" + continue-on-error: ${{ matrix.continue_on_error || false }} strategy: matrix: - include: "${{ fromJSON(needs.calculate_matrix.outputs.jobs) }}" - if: "fromJSON(needs.calculate_matrix.outputs.jobs)[0] != null" + # Check the `calculate_matrix` job to see how is the matrix defined. + include: ${{ fromJSON(needs.calculate_matrix.outputs.jobs) }} + # GitHub Actions fails the workflow if an empty list of jobs is provided to + # the workflow, so we need to skip this job if nothing was produced by + # the Python script. + # + # Unfortunately checking whether a list is empty is not possible in a nice + # way due to GitHub Actions expressions limits. + # This hack is taken from https://github.com/ferrocene/ferrocene/blob/d43edc6b7697cf1719ec1c17c54904ab94825763/.github/workflows/release.yml#L75-L82 + if: fromJSON(needs.calculate_matrix.outputs.jobs)[0] != null steps: - - if: "contains(matrix.os, 'windows')" + - if: contains(matrix.os, 'windows') uses: msys2/setup-msys2@v2.22.0 with: - msystem: "${{ contains(matrix.name, 'i686') && 'mingw32' || 'mingw64' }}" + # i686 jobs use mingw32. x86_64 and cross-compile jobs use mingw64. + msystem: ${{ contains(matrix.name, 'i686') && 'mingw32' || 'mingw64' }} + # don't try to download updates for already installed packages update: false + # don't try to use the msys that comes built-in to the github runner, + # so we can control what is installed (i.e. not python) release: true + # Inherit the full path from the Windows environment, with MSYS2's */bin/ + # dirs placed in front. This lets us run Windows-native Python etc. path-type: inherit - install: "make dos2unix diffutils\n" + install: > + make + dos2unix + diffutils + - name: disable git crlf conversion run: git config --global core.autocrlf false + - name: checkout the source code uses: actions/checkout@v4 with: fetch-depth: 2 + + # Rust Log Analyzer can't currently detect the PR number of a GitHub + # Actions build on its own, so a hint in the log message is needed to + # point it in the right direction. - name: configure the PR in which the error message will be posted - run: "echo \"[CI_PR_NUMBER=$num]\"" + run: echo "[CI_PR_NUMBER=$num]" env: - num: "${{ github.event.number }}" - if: "success() && github.event_name == 'pull_request'" + num: ${{ github.event.number }} + if: success() && github.event_name == 'pull_request' + - name: add extra environment variables run: src/ci/scripts/setup-environment.sh env: - EXTRA_VARIABLES: "${{ toJson(matrix.env) }}" + # Since it's not possible to merge `${{ matrix.env }}` with the other + # variables in `job..env`, the variables defined in the matrix + # are passed to the `setup-environment.sh` script encoded in JSON, + # which then uses log commands to actually set them. + EXTRA_VARIABLES: ${{ toJson(matrix.env) }} + - name: ensure the channel matches the target branch run: src/ci/scripts/verify-channel.sh + - name: collect CPU statistics run: src/ci/scripts/collect-cpu-stats.sh + - name: show the current environment run: src/ci/scripts/dump-environment.sh + - name: install awscli run: src/ci/scripts/install-awscli.sh + - name: install sccache run: src/ci/scripts/install-sccache.sh + - name: select Xcode run: src/ci/scripts/select-xcode.sh + - name: install clang run: src/ci/scripts/install-clang.sh + - name: install tidy run: src/ci/scripts/install-tidy.sh + - name: install WIX run: src/ci/scripts/install-wix.sh + - name: disable git crlf conversion run: src/ci/scripts/disable-git-crlf-conversion.sh + - name: checkout submodules run: src/ci/scripts/checkout-submodules.sh + - name: install MSYS2 run: src/ci/scripts/install-msys2.sh + - name: install MinGW run: src/ci/scripts/install-mingw.sh + - name: install ninja run: src/ci/scripts/install-ninja.sh + - name: enable ipv6 on Docker run: src/ci/scripts/enable-docker-ipv6.sh + + # Disable automatic line ending conversion (again). On Windows, when we're + # installing dependencies, something switches the git configuration directory or + # re-enables autocrlf. We've not tracked down the exact cause -- and there may + # be multiple -- but this should ensure submodules are checked out with the + # appropriate line endings. - name: disable git crlf conversion run: src/ci/scripts/disable-git-crlf-conversion.sh + - name: ensure line endings are correct run: src/ci/scripts/verify-line-endings.sh + - name: ensure backported commits are in upstream branches run: src/ci/scripts/verify-backported-commits.sh + - name: ensure the stable version number is correct run: src/ci/scripts/verify-stable-version-number.sh + - name: run the build + # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs. run: src/ci/scripts/run-build-from-ci.sh 2>&1 env: - AWS_ACCESS_KEY_ID: "${{ env.CACHES_AWS_ACCESS_KEY_ID }}" - AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}" - TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}" + AWS_ACCESS_KEY_ID: ${{ env.CACHES_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }} + TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }} + - name: create github artifacts run: src/ci/scripts/create-doc-artifacts.sh + - name: upload artifacts to github uses: actions/upload-artifact@v4 with: - name: "${{ env.DOC_ARTIFACT_NAME }}" + # name is set in previous step + name: ${{ env.DOC_ARTIFACT_NAME }} path: obj/artifacts/doc if-no-files-found: ignore retention-days: 5 + - name: upload artifacts to S3 run: src/ci/scripts/upload-artifacts.sh env: - AWS_ACCESS_KEY_ID: "${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }}" - AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }}" - if: "success() && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')" + AWS_ACCESS_KEY_ID: ${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }} + # Adding a condition on DEPLOY=1 or DEPLOY_ALT=1 is not needed as all deploy + # builders *should* have the AWS credentials available. Still, explicitly + # adding the condition is helpful as this way CI will not silently skip + # deploying artifacts from a dist builder if the variables are misconfigured, + # erroring about invalid credentials instead. + if: success() && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1') + + # This job isused to tell bors the final status of the build, as there is no practical way to detect + # when a workflow is successful listening to webhooks only in our current bors implementation (homu). outcome: name: bors build finished runs-on: ubuntu-latest - needs: - - job + needs: [ job ] + # !cancelled() executes the job regardless of whether the previous jobs passed or failed if: "!cancelled() && github.event_name == 'push'" steps: - name: checkout the source code uses: actions/checkout@v4 with: fetch-depth: 2 + # Calculate the exit status of the whole CI workflow. + # If all dependent jobs were successful, this exits with 0 (and the outcome job continues successfully). + # If a some dependent job has failed, this exits with 1. - name: calculate the correct exit status - id: status - run: "jq --exit-status 'all(.result == \"success\" or .result == \"skipped\")' <<< '${{ toJson(needs) }}'\necho \"status=$?\" >> $GITHUB_OUTPUT\n" + run: jq --exit-status 'all(.result == "success" or .result == "skipped")' <<< '${{ toJson(needs) }}' + # Publish the toolstate if an auto build succeeds (just before push to master) - name: publish toolstate run: src/ci/publish_toolstate.sh shell: bash - if: "steps.outputs.status == 0 && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" + if: success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust' env: - TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}" - - name: set the correct exit status - run: "exit ${{ steps.outputs.status == 0 }}" + TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }} diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml deleted file mode 100644 index 4ca7b52bc02d..000000000000 --- a/src/ci/github-actions/ci.yml +++ /dev/null @@ -1,301 +0,0 @@ -###################################################### -# WARNING! Action needed when changing this file # -###################################################### - -# Due to GitHub Actions limitations, we can't use YAML Anchors directly in the -# CI configuration stored on the repository. To work around that this file is -# expanded by a tool in the repository, and the expansion is committed as well. -# -# After you make any change to the file you'll need to run this command: -# -# ./x.py run src/tools/expand-yaml-anchors -# -# ...and commit the file it updated in addition to this one. If you forget this -# step CI will fail. - ---- -############################### -# YAML Anchors Definition # -############################### - -# This key contains most of the YAML anchors that will be used later in the -# document. YAML anchors allows us to greatly reduce duplication inside the CI -# configuration by reusing parts of the configuration. -# -# YAML anchors work by defining an anchor with `&anchor-name` and reusing its -# content in another place with `*anchor-name`. The special `<<` map key merges -# the content of the map with the content of the anchor (or list of anchors). -# -# The expand-yaml-anchors tool will automatically remove this block from the -# output YAML file. -x--expand-yaml-anchors--remove: - # These snippets are used by the try-success, try-failure, auto-success and auto-failure jobs. - # Check out their documentation for more information on why they're needed. - - - &base-outcome-job - name: bors build finished - runs-on: ubuntu-latest - - - &base-success-job - steps: - - name: mark the job as a success - run: exit 0 - shell: bash - <<: *base-outcome-job - - - &base-failure-job - steps: - - name: mark the job as a failure - run: exit 1 - shell: bash - <<: *base-outcome-job - -########################### -# Builders definition # -########################### - -name: CI -on: - push: - branches: - - auto - - try - - try-perf - - automation/bors/try - pull_request: - branches: - - "**" - -permissions: - contents: read - packages: write - -defaults: - run: - # On Linux, macOS, and Windows, use the system-provided bash as the default - # shell. (This should only make a difference on Windows, where the default - # shell is PowerShell.) - shell: bash - -concurrency: - # For a given workflow, if we push to the same branch, cancel all previous builds on that branch. - # We add an exception for try builds (try branch) and unrolled rollup builds (try-perf), which - # are all triggered on the same branch, but which should be able to run concurrently. - group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }} - cancel-in-progress: true - -env: - TOOLSTATE_REPO: https://github.com/rust-lang-nursery/rust-toolstate - -jobs: - # The job matrix for `calculate_matrix` is defined in src/ci/github-actions/jobs.yml. - # It calculates which jobs should be executed, based on the data of the ${{ github }} context. - # If you want to modify CI jobs, take a look at src/ci/github-actions/jobs.yml. - calculate_matrix: - name: Calculate job matrix - runs-on: ubuntu-latest - outputs: - jobs: ${{ steps.jobs.outputs.jobs }} - steps: - - name: Checkout the source code - uses: actions/checkout@v4 - - name: Calculate the CI job matrix - run: python3 src/ci/github-actions/calculate-job-matrix.py >> $GITHUB_OUTPUT - id: jobs - job: - name: ${{ matrix.name }} - needs: [ calculate_matrix ] - runs-on: "${{ matrix.os }}" - defaults: - run: - shell: ${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }} - timeout-minutes: 600 - env: - CI_JOB_NAME: ${{ matrix.image }} - CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - # commit of PR sha or commit sha. `GITHUB_SHA` is not accurate for PRs. - HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} - DOCKER_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SCCACHE_BUCKET: rust-lang-ci-sccache2 - CACHE_DOMAIN: ci-caches.rust-lang.org - continue-on-error: ${{ matrix.continue_on_error || false }} - strategy: - matrix: - # Check the `calculate_matrix` job to see how is the matrix defined. - include: ${{ fromJSON(needs.calculate_matrix.outputs.jobs) }} - # GitHub Actions fails the workflow if an empty list of jobs is provided to - # the workflow, so we need to skip this job if nothing was produced by - # the Python script. - # - # Unfortunately checking whether a list is empty is not possible in a nice - # way due to GitHub Actions expressions limits. - # This hack is taken from https://github.com/ferrocene/ferrocene/blob/d43edc6b7697cf1719ec1c17c54904ab94825763/.github/workflows/release.yml#L75-L82 - if: fromJSON(needs.calculate_matrix.outputs.jobs)[0] != null - steps: - - if: contains(matrix.os, 'windows') - uses: msys2/setup-msys2@v2.22.0 - with: - # i686 jobs use mingw32. x86_64 and cross-compile jobs use mingw64. - msystem: ${{ contains(matrix.name, 'i686') && 'mingw32' || 'mingw64' }} - # don't try to download updates for already installed packages - update: false - # don't try to use the msys that comes built-in to the github runner, - # so we can control what is installed (i.e. not python) - release: true - # Inherit the full path from the Windows environment, with MSYS2's */bin/ - # dirs placed in front. This lets us run Windows-native Python etc. - path-type: inherit - install: > - make - dos2unix - diffutils - - - name: disable git crlf conversion - run: git config --global core.autocrlf false - - - name: checkout the source code - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - # Rust Log Analyzer can't currently detect the PR number of a GitHub - # Actions build on its own, so a hint in the log message is needed to - # point it in the right direction. - - name: configure the PR in which the error message will be posted - run: echo "[CI_PR_NUMBER=$num]" - env: - num: ${{ github.event.number }} - if: success() && github.event_name == 'pull_request' - - - name: add extra environment variables - run: src/ci/scripts/setup-environment.sh - env: - # Since it's not possible to merge `${{ matrix.env }}` with the other - # variables in `job..env`, the variables defined in the matrix - # are passed to the `setup-environment.sh` script encoded in JSON, - # which then uses log commands to actually set them. - EXTRA_VARIABLES: ${{ toJson(matrix.env) }} - - - name: ensure the channel matches the target branch - run: src/ci/scripts/verify-channel.sh - - - name: collect CPU statistics - run: src/ci/scripts/collect-cpu-stats.sh - - - name: show the current environment - run: src/ci/scripts/dump-environment.sh - - - name: install awscli - run: src/ci/scripts/install-awscli.sh - - - name: install sccache - run: src/ci/scripts/install-sccache.sh - - - name: select Xcode - run: src/ci/scripts/select-xcode.sh - - - name: install clang - run: src/ci/scripts/install-clang.sh - - - name: install tidy - run: src/ci/scripts/install-tidy.sh - - - name: install WIX - run: src/ci/scripts/install-wix.sh - - - name: disable git crlf conversion - run: src/ci/scripts/disable-git-crlf-conversion.sh - - - name: checkout submodules - run: src/ci/scripts/checkout-submodules.sh - - - name: install MSYS2 - run: src/ci/scripts/install-msys2.sh - - - name: install MinGW - run: src/ci/scripts/install-mingw.sh - - - name: install ninja - run: src/ci/scripts/install-ninja.sh - - - name: enable ipv6 on Docker - run: src/ci/scripts/enable-docker-ipv6.sh - - # Disable automatic line ending conversion (again). On Windows, when we're - # installing dependencies, something switches the git configuration directory or - # re-enables autocrlf. We've not tracked down the exact cause -- and there may - # be multiple -- but this should ensure submodules are checked out with the - # appropriate line endings. - - name: disable git crlf conversion - run: src/ci/scripts/disable-git-crlf-conversion.sh - - - name: ensure line endings are correct - run: src/ci/scripts/verify-line-endings.sh - - - name: ensure backported commits are in upstream branches - run: src/ci/scripts/verify-backported-commits.sh - - - name: ensure the stable version number is correct - run: src/ci/scripts/verify-stable-version-number.sh - - - name: run the build - # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs. - run: src/ci/scripts/run-build-from-ci.sh 2>&1 - env: - AWS_ACCESS_KEY_ID: ${{ env.CACHES_AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }} - TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }} - - - name: create github artifacts - run: src/ci/scripts/create-doc-artifacts.sh - - - name: upload artifacts to github - uses: actions/upload-artifact@v4 - with: - # name is set in previous step - name: ${{ env.DOC_ARTIFACT_NAME }} - path: obj/artifacts/doc - if-no-files-found: ignore - retention-days: 5 - - - name: upload artifacts to S3 - run: src/ci/scripts/upload-artifacts.sh - env: - AWS_ACCESS_KEY_ID: ${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }} - # Adding a condition on DEPLOY=1 or DEPLOY_ALT=1 is not needed as all deploy - # builders *should* have the AWS credentials available. Still, explicitly - # adding the condition is helpful as this way CI will not silently skip - # deploying artifacts from a dist builder if the variables are misconfigured, - # erroring about invalid credentials instead. - if: success() && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1') - - # This job isused to tell bors the final status of the build, as there is no practical way to detect - # when a workflow is successful listening to webhooks only in our current bors implementation (homu). - outcome: - name: bors build finished - runs-on: ubuntu-latest - needs: [ job ] - # !cancelled() executes the job regardless of whether the previous jobs passed or failed - if: "!cancelled() && github.event_name == 'push'" - steps: - - name: checkout the source code - uses: actions/checkout@v4 - with: - fetch-depth: 2 - # Calculate the exit status of the whole CI workflow (0 if all dependent jobs were either successful - # or skipped, otherwise 1). - - name: calculate the correct exit status - id: status - run: | - jq --exit-status 'all(.result == "success" or .result == "skipped")' <<< '${{ toJson(needs) }}' - echo "status=$?" >> $GITHUB_OUTPUT - # Publish the toolstate if an auto build succeeds (just before push to master) - - name: publish toolstate - run: src/ci/publish_toolstate.sh - shell: bash - if: steps.outputs.status == 0 && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust' - env: - TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }} - - name: set the correct exit status - run: exit ${{ steps.outputs.status }} From 0b1ecf1d8d9318eedf68c855ac1112f0063dd495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 25 Apr 2024 11:13:37 +0200 Subject: [PATCH 178/279] Remove the `expand-yaml-anchors` tool --- Cargo.lock | 34 --- Cargo.toml | 1 - src/bootstrap/src/core/build_steps/run.rs | 26 --- src/bootstrap/src/core/build_steps/test.rs | 35 ---- src/bootstrap/src/core/build_steps/tool.rs | 1 - src/bootstrap/src/core/builder.rs | 2 - src/bootstrap/src/core/config/flags.rs | 2 +- .../docker/host-x86_64/mingw-check/Dockerfile | 9 +- src/ci/github-actions/jobs.yml | 2 - src/tools/expand-yaml-anchors/Cargo.toml | 8 - src/tools/expand-yaml-anchors/src/main.rs | 198 ------------------ 11 files changed, 5 insertions(+), 313 deletions(-) delete mode 100644 src/tools/expand-yaml-anchors/Cargo.toml delete mode 100644 src/tools/expand-yaml-anchors/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index ac6e7974a127..05ec7bef318f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1254,14 +1254,6 @@ dependencies = [ "mdbook", ] -[[package]] -name = "expand-yaml-anchors" -version = "0.1.0" -dependencies = [ - "yaml-merge-keys", - "yaml-rust", -] - [[package]] name = "expect-test" version = "1.5.0" @@ -2236,12 +2228,6 @@ dependencies = [ "regex", ] -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - [[package]] name = "lint-docs" version = "0.1.0" @@ -6547,26 +6533,6 @@ dependencies = [ "lzma-sys", ] -[[package]] -name = "yaml-merge-keys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd236a7dc9bb598f349fe4a8754f49181fee50284daa15cd1ba652d722280004" -dependencies = [ - "lazy_static", - "thiserror", - "yaml-rust", -] - -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - [[package]] name = "yansi-term" version = "0.1.2" diff --git a/Cargo.toml b/Cargo.toml index 1379e4cd3bfd..a601ebf4369e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,6 @@ members = [ "src/tools/miri/cargo-miri", "src/tools/rustdoc-themes", "src/tools/unicode-table-generator", - "src/tools/expand-yaml-anchors", "src/tools/jsondocck", "src/tools/jsondoclint", "src/tools/llvm-bitcode-linker", diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 0a428ec5ca0a..354eb2b60038 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -15,32 +15,6 @@ use crate::core::config::TargetSelection; use crate::utils::helpers::output; use crate::Mode; -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ExpandYamlAnchors; - -impl Step for ExpandYamlAnchors { - type Output = (); - - /// Runs the `expand-yaml_anchors` tool. - /// - /// This tool in `src/tools` reads the CI configuration files written in YAML and expands the - /// anchors in them, since GitHub Actions doesn't support them. - fn run(self, builder: &Builder<'_>) { - builder.info("Expanding YAML anchors in the GitHub Actions configuration"); - builder.run_delaying_failure( - builder.tool_cmd(Tool::ExpandYamlAnchors).arg("generate").arg(&builder.src), - ); - } - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/tools/expand-yaml-anchors") - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(ExpandYamlAnchors); - } -} - #[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)] pub struct BuildManifest; diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 411ed99532f7..9a585a39e1ee 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1146,8 +1146,6 @@ HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to builder.info("tidy check"); builder.run_delaying_failure(&mut cmd); - builder.ensure(ExpandYamlAnchors); - builder.info("x.py completions check"); let [bash, zsh, fish, powershell] = ["x.py.sh", "x.py.zsh", "x.py.fish", "x.py.ps1"] .map(|filename| builder.src.join("src/etc/completions").join(filename)); @@ -1175,39 +1173,6 @@ HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to } } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ExpandYamlAnchors; - -impl Step for ExpandYamlAnchors { - type Output = (); - const ONLY_HOSTS: bool = true; - - /// Ensure the `generate-ci-config` tool was run locally. - /// - /// The tool in `src/tools` reads the CI definition in `src/ci/builders.yml` and generates the - /// appropriate configuration for all our CI providers. This step ensures the tool was called - /// by the user before committing CI changes. - fn run(self, builder: &Builder<'_>) { - // NOTE: `.github/` is not included in dist-src tarballs - if !builder.src.join(".github/workflows/ci.yml").exists() { - builder.info("Skipping YAML anchors check: GitHub Actions config not found"); - return; - } - builder.info("Ensuring the YAML anchors in the GitHub Actions config were expanded"); - builder.run_delaying_failure( - builder.tool_cmd(Tool::ExpandYamlAnchors).arg("check").arg(&builder.src), - ); - } - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/tools/expand-yaml-anchors") - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(ExpandYamlAnchors); - } -} - fn testdir(builder: &Builder<'_>, host: TargetSelection) -> PathBuf { builder.out.join(host.triple).join("test") } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 994f0bef0dc7..2e2c5e9e6f8b 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -302,7 +302,6 @@ bootstrap_tool!( RemoteTestClient, "src/tools/remote-test-client", "remote-test-client"; RustInstaller, "src/tools/rust-installer", "rust-installer"; RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes"; - ExpandYamlAnchors, "src/tools/expand-yaml-anchors", "expand-yaml-anchors"; LintDocs, "src/tools/lint-docs", "lint-docs"; JsonDocCk, "src/tools/jsondocck", "jsondocck"; JsonDocLint, "src/tools/jsondoclint", "jsondoclint"; diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index ae5440de5729..07488282983f 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -791,7 +791,6 @@ impl<'a> Builder<'a> { ), Kind::Test => describe!( crate::core::build_steps::toolstate::ToolStateCheck, - test::ExpandYamlAnchors, test::Tidy, test::Ui, test::Crashes, @@ -933,7 +932,6 @@ impl<'a> Builder<'a> { install::Src, ), Kind::Run => describe!( - run::ExpandYamlAnchors, run::BuildManifest, run::BumpStage0, run::ReplaceVersionPlaceholder, diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index a5af87ad5c72..f4ed7e76fba1 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -420,7 +420,7 @@ pub enum Subcommand { Arguments: This subcommand accepts a number of paths to tools to build and run. For example: - ./x.py run src/tools/expand-yaml-anchors + ./x.py run src/tools/bump-stage0 At least a tool needs to be called.")] /// Run tools contained in this repository Run { diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile index 0eff7ca5962b..d0da7d306601 100644 --- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile +++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile @@ -42,11 +42,10 @@ COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/ ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1 -ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \ - # Check library crates on all tier 1 targets. - # We disable optimized compiler built-ins because that requires a C toolchain for the target. - # We also skip the x86_64-unknown-linux-gnu target as it is well-tested by other jobs. - python3 ../x.py check --stage 0 --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \ +# Check library crates on all tier 1 targets. +# We disable optimized compiler built-ins because that requires a C toolchain for the target. +# We also skip the x86_64-unknown-linux-gnu target as it is well-tested by other jobs. +ENV SCRIPT python3 ../x.py check --stage 0 --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \ python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \ python3 ../x.py clippy bootstrap -Dwarnings && \ python3 ../x.py clippy compiler library -Aclippy::all -Dclippy::correctness && \ diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index df6c5d6079d1..1fabf889e38a 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -1,7 +1,5 @@ # This file contains definitions of CI job parameters that are loaded # dynamically in CI from ci.yml. -# You *do not* need to re-run `src/tools/expand-yaml-anchors` when you -# modify this file. runners: - &base-job env: { } diff --git a/src/tools/expand-yaml-anchors/Cargo.toml b/src/tools/expand-yaml-anchors/Cargo.toml deleted file mode 100644 index 9a25b6c1f1c8..000000000000 --- a/src/tools/expand-yaml-anchors/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "expand-yaml-anchors" -version = "0.1.0" -edition = "2021" - -[dependencies] -yaml-rust = "0.4.3" -yaml-merge-keys = "0.4.0" diff --git a/src/tools/expand-yaml-anchors/src/main.rs b/src/tools/expand-yaml-anchors/src/main.rs deleted file mode 100644 index 60651734b9e3..000000000000 --- a/src/tools/expand-yaml-anchors/src/main.rs +++ /dev/null @@ -1,198 +0,0 @@ -use std::error::Error; -use std::path::{Path, PathBuf}; -use yaml_rust::{Yaml, YamlEmitter, YamlLoader}; - -/// List of files to expand. The first tuple element is the source -/// file, while the second tuple element is the destination file. -#[rustfmt::skip] -static TO_EXPAND: &[(&str, &str)] = &[ - ("src/ci/github-actions/ci.yml", ".github/workflows/ci.yml"), -]; - -/// Name of a special key that will be removed from all the maps in expanded configuration files. -/// This key can then be used to contain shared anchors. -static REMOVE_MAP_KEY: &str = "x--expand-yaml-anchors--remove"; - -/// Message that will be included at the top of all the expanded files. {source} will be replaced -/// with the source filename relative to the base path. -static HEADER_MESSAGE: &str = "\ -############################################################# -# WARNING: automatically generated file, DO NOT CHANGE! # -############################################################# - -# This file was automatically generated by the expand-yaml-anchors tool. The -# source file that generated this one is: -# -# {source} -# -# Once you make changes to that file you need to run: -# -# ./x.py run src/tools/expand-yaml-anchors/ -# -# The CI build will fail if the tool is not run after changes to this file. - -"; - -enum Mode { - Check, - Generate, -} - -struct App { - mode: Mode, - base: PathBuf, -} - -impl App { - fn from_args() -> Result> { - // Parse CLI arguments - let args = std::env::args().skip(1).collect::>(); - let (mode, base) = match args.iter().map(|s| s.as_str()).collect::>().as_slice() { - ["generate", ref base] => (Mode::Generate, PathBuf::from(base)), - ["check", ref base] => (Mode::Check, PathBuf::from(base)), - _ => { - eprintln!("usage: expand-yaml-anchors "); - std::process::exit(1); - } - }; - - Ok(App { mode, base }) - } - - fn run(&self) -> Result<(), Box> { - for (source, dest) in TO_EXPAND { - let source = self.base.join(source); - let dest_path = self.base.join(dest); - - self.expand(&source, &dest_path).with_context(|| match self.mode { - Mode::Generate => format!( - "failed to expand {} into {}", - self.path(&source), - self.path(&dest_path) - ), - Mode::Check => format!( - "{} is not up to date; please run \ - `x.py run src/tools/expand-yaml-anchors`.", - self.path(&dest_path) - ), - })?; - } - Ok(()) - } - - fn expand(&self, source: &Path, dest: &Path) -> Result<(), Box> { - let content = std::fs::read_to_string(source) - .with_context(|| format!("failed to read {}", self.path(source)))?; - - let mut buf = - HEADER_MESSAGE.replace("{source}", &self.path(source).to_string().replace("\\", "/")); - - let documents = YamlLoader::load_from_str(&content) - .with_context(|| format!("failed to parse {}", self.path(source)))?; - for mut document in documents.into_iter() { - document = yaml_merge_keys::merge_keys(document) - .with_context(|| format!("failed to expand {}", self.path(source)))?; - document = filter_document(document); - - YamlEmitter::new(&mut buf).dump(&document).map_err(|err| WithContext { - context: "failed to serialize the expanded yaml".into(), - source: Box::new(err), - })?; - buf.push('\n'); - } - - match self.mode { - Mode::Check => { - let old = std::fs::read_to_string(dest) - .with_context(|| format!("failed to read {}", self.path(dest)))?; - if old != buf { - return Err(Box::new(StrError(format!( - "{} and {} are different", - self.path(source), - self.path(dest), - )))); - } - } - Mode::Generate => { - std::fs::write(dest, buf.as_bytes()) - .with_context(|| format!("failed to write to {}", self.path(dest)))?; - } - } - Ok(()) - } - - fn path<'a>(&self, path: &'a Path) -> impl std::fmt::Display + 'a { - path.strip_prefix(&self.base).unwrap_or(path).display() - } -} - -fn filter_document(document: Yaml) -> Yaml { - match document { - Yaml::Hash(map) => Yaml::Hash( - map.into_iter() - .filter(|(key, _)| { - if let Yaml::String(string) = &key { string != REMOVE_MAP_KEY } else { true } - }) - .map(|(key, value)| (filter_document(key), filter_document(value))) - .collect(), - ), - Yaml::Array(vec) => Yaml::Array(vec.into_iter().map(filter_document).collect()), - other => other, - } -} - -fn main() { - if let Err(err) = App::from_args().and_then(|app| app.run()) { - eprintln!("error: {}", err); - - let mut source = err.as_ref() as &dyn Error; - while let Some(err) = source.source() { - eprintln!("caused by: {}", err); - source = err; - } - - std::process::exit(1); - } -} - -#[derive(Debug)] -struct StrError(String); - -impl Error for StrError {} - -impl std::fmt::Display for StrError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.0, f) - } -} - -#[derive(Debug)] -struct WithContext { - context: String, - source: Box, -} - -impl std::fmt::Display for WithContext { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.context) - } -} - -impl Error for WithContext { - fn source(&self) -> Option<&(dyn Error + 'static)> { - Some(self.source.as_ref()) - } -} - -pub(crate) trait ResultExt { - fn with_context String>(self, f: F) -> Result>; -} - -impl>> ResultExt for Result { - fn with_context String>(self, f: F) -> Result> { - match self { - Ok(ok) => Ok(ok), - Err(err) => Err(WithContext { source: err.into(), context: f() }.into()), - } - } -} From 686baf55894eca650cdef1a476533d1f74662511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 27 Apr 2024 11:51:31 +0200 Subject: [PATCH 179/279] Remove redundant `success()` condition --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6fdc8d4d72dd..a62c18ddf6b8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -243,6 +243,6 @@ jobs: - name: publish toolstate run: src/ci/publish_toolstate.sh shell: bash - if: success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust' + if: github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust' env: TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }} From 24bf3594a58d47b8d3bc65bb80ba7155fde48a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 27 Apr 2024 11:56:39 +0200 Subject: [PATCH 180/279] Rename `JobType` to `WorkflowRunType` --- src/ci/github-actions/calculate-job-matrix.py | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ci/github-actions/calculate-job-matrix.py b/src/ci/github-actions/calculate-job-matrix.py index 124c22bd979f..62cc867fac79 100755 --- a/src/ci/github-actions/calculate-job-matrix.py +++ b/src/ci/github-actions/calculate-job-matrix.py @@ -44,7 +44,7 @@ def add_base_env(jobs: List[Job], environment: Dict[str, str]) -> List[Job]: return jobs -class JobType(enum.Enum): +class WorkflowRunType(enum.Enum): PR = enum.auto() Try = enum.auto() Auto = enum.auto() @@ -57,9 +57,9 @@ class GitHubCtx: repository: str -def find_job_type(ctx: GitHubCtx) -> Optional[JobType]: +def find_run_type(ctx: GitHubCtx) -> Optional[WorkflowRunType]: if ctx.event_name == "pull_request": - return JobType.PR + return WorkflowRunType.PR elif ctx.event_name == "push": old_bors_try_build = ( ctx.ref in ("refs/heads/try", "refs/heads/try-perf") and @@ -72,20 +72,20 @@ def find_job_type(ctx: GitHubCtx) -> Optional[JobType]: try_build = old_bors_try_build or new_bors_try_build if try_build: - return JobType.Try + return WorkflowRunType.Try if ctx.ref == "refs/heads/auto" and ctx.repository == "rust-lang-ci/rust": - return JobType.Auto + return WorkflowRunType.Auto return None -def calculate_jobs(job_type: JobType, job_data: Dict[str, Any]) -> List[Job]: - if job_type == JobType.PR: +def calculate_jobs(run_type: WorkflowRunType, job_data: Dict[str, Any]) -> List[Job]: + if run_type == WorkflowRunType.PR: return add_base_env(name_jobs(job_data["pr"], "PR"), job_data["envs"]["pr"]) - elif job_type == JobType.Try: + elif run_type == WorkflowRunType.Try: return add_base_env(name_jobs(job_data["try"], "try"), job_data["envs"]["try"]) - elif job_type == JobType.Auto: + elif run_type == WorkflowRunType.Auto: return add_base_env(name_jobs(job_data["auto"], "auto"), job_data["envs"]["auto"]) return [] @@ -114,15 +114,15 @@ if __name__ == "__main__": github_ctx = get_github_ctx() - job_type = find_job_type(github_ctx) - logging.info(f"Job type: {job_type}") + run_type = find_run_type(github_ctx) + logging.info(f"Job type: {run_type}") with open(CI_DIR / "channel") as f: channel = f.read().strip() jobs = [] - if job_type is not None: - jobs = calculate_jobs(job_type, data) + if run_type is not None: + jobs = calculate_jobs(run_type, data) jobs = skip_jobs(jobs, channel) logging.info(f"Output:\n{yaml.dump(jobs, indent=4)}") From adbc84cfacc1d6b73864cdf62592f8db507b6ac3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 27 Apr 2024 12:02:05 +0200 Subject: [PATCH 181/279] Remove redundant `success` expressions from steps --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a62c18ddf6b8..6f63bdce0aab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -116,7 +116,7 @@ jobs: run: echo "[CI_PR_NUMBER=$num]" env: num: ${{ github.event.number }} - if: success() && github.event_name == 'pull_request' + if: github.event_name == 'pull_request' - name: add extra environment variables run: src/ci/scripts/setup-environment.sh @@ -219,7 +219,7 @@ jobs: # adding the condition is helpful as this way CI will not silently skip # deploying artifacts from a dist builder if the variables are misconfigured, # erroring about invalid credentials instead. - if: success() && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1') + if: github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1' # This job isused to tell bors the final status of the build, as there is no practical way to detect # when a workflow is successful listening to webhooks only in our current bors implementation (homu). From b194d5ce4460a843ba40cfc48d0073a455905711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 27 Apr 2024 12:09:18 +0200 Subject: [PATCH 182/279] Output `run_type` from the matrix calculation job --- .github/workflows/ci.yml | 9 +++++---- src/ci/github-actions/calculate-job-matrix.py | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6f63bdce0aab..a2769a2c2749 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,6 +47,7 @@ jobs: runs-on: ubuntu-latest outputs: jobs: ${{ steps.jobs.outputs.jobs }} + run_type: ${{ steps.jobs.outputs.run_type }} steps: - name: Checkout the source code uses: actions/checkout@v4 @@ -116,7 +117,7 @@ jobs: run: echo "[CI_PR_NUMBER=$num]" env: num: ${{ github.event.number }} - if: github.event_name == 'pull_request' + if: needs.calculate_matrix.outputs.run_type == 'pr' - name: add extra environment variables run: src/ci/scripts/setup-environment.sh @@ -226,9 +227,9 @@ jobs: outcome: name: bors build finished runs-on: ubuntu-latest - needs: [ job ] + needs: [ calculate_matrix, job ] # !cancelled() executes the job regardless of whether the previous jobs passed or failed - if: "!cancelled() && github.event_name == 'push'" + if: ${{ !cancelled() && contains(fromJSON('["auto", "try"]'), needs.calculate_matrix.outputs.run_type) }} steps: - name: checkout the source code uses: actions/checkout@v4 @@ -243,6 +244,6 @@ jobs: - name: publish toolstate run: src/ci/publish_toolstate.sh shell: bash - if: github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust' + if: needs.calculate_matrix.outputs.run_type == 'auto' env: TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }} diff --git a/src/ci/github-actions/calculate-job-matrix.py b/src/ci/github-actions/calculate-job-matrix.py index 62cc867fac79..68565f489c93 100755 --- a/src/ci/github-actions/calculate-job-matrix.py +++ b/src/ci/github-actions/calculate-job-matrix.py @@ -106,6 +106,17 @@ def get_github_ctx() -> GitHubCtx: ) +def format_run_type(run_type: WorkflowRunType) -> str: + if run_type == WorkflowRunType.PR: + return "pr" + elif run_type == WorkflowRunType.Auto: + return "auto" + elif run_type == WorkflowRunType.Try: + return "try" + else: + raise AssertionError() + + if __name__ == "__main__": logging.basicConfig(level=logging.INFO) @@ -124,6 +135,8 @@ if __name__ == "__main__": if run_type is not None: jobs = calculate_jobs(run_type, data) jobs = skip_jobs(jobs, channel) + run_type = format_run_type(run_type) - logging.info(f"Output:\n{yaml.dump(jobs, indent=4)}") + logging.info(f"Output:\n{yaml.dump(dict(jobs=jobs, run_type=run_type), indent=4)}") print(f"jobs={json.dumps(jobs)}") + print(f"run_type={run_type}") From 7ac1529ff630eeefb96888d734ae26bb6e84e335 Mon Sep 17 00:00:00 2001 From: xFrednet Date: Mon, 29 Apr 2024 21:44:16 +0200 Subject: [PATCH 183/279] Changelog for Clippy 1.78 :magic_wand: --- CHANGELOG.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12d4918ca55e..d908ed43cfae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,75 @@ document. ## Unreleased / Beta / In Rust Nightly -[66c29b97...master](https://github.com/rust-lang/rust-clippy/compare/66c29b97...master) +[93f0a9a9...master](https://github.com/rust-lang/rust-clippy/compare/93f0a9a9...master) + +## Rust 1.78 + +Current stable, released 2024-05-02 + +[View all 112 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-01-26T05%3A46%3A23Z..2024-03-07T16%3A25%3A52Z+base%3Amaster) + +### Important Changes + +* In a few versions, `cargo-clippy` will now no longer ignore the first argument. + Passing in `clippy` as the first argument like cargo does will continue to work. + However, arguments like `--fix` will soon issue a warning and will no longer be. + `cargo clippy` (without `-`!) is unaffected by this change. + [#9461](https://github.com/rust-lang/rust-clippy/pull/9461) + +### New Lints + +* [`assigning_clones`] + [#12077](https://github.com/rust-lang/rust-clippy/pull/12077) +* [`mixed_attributes_style`] + [#12354](https://github.com/rust-lang/rust-clippy/pull/12354) +* [`empty_docs`] + [#12342](https://github.com/rust-lang/rust-clippy/pull/12342) +* [`unnecessary_get_then_check`] + [#12339](https://github.com/rust-lang/rust-clippy/pull/12339) +* [`multiple_bound_locations`] + [#12259](https://github.com/rust-lang/rust-clippy/pull/12259) +* [`unnecessary_clippy_cfg`] + [#12303](https://github.com/rust-lang/rust-clippy/pull/12303) +* [`deprecated_clippy_cfg_attr`] + [#12292](https://github.com/rust-lang/rust-clippy/pull/12292) +* [`manual_c_str_literals`] + [#11919](https://github.com/rust-lang/rust-clippy/pull/11919) +* [`ref_as_ptr`] + [#12087](https://github.com/rust-lang/rust-clippy/pull/12087) +* [`lint_groups_priority`] + [#11832](https://github.com/rust-lang/rust-clippy/pull/11832) +* [`unnecessary_result_map_or_else`] + [#12169](https://github.com/rust-lang/rust-clippy/pull/12169) +* [`to_string_trait_impl`] + [#12122](https://github.com/rust-lang/rust-clippy/pull/12122) +* [`incompatible_msrv`] + [#12160](https://github.com/rust-lang/rust-clippy/pull/12160) + +### Moves and Deprecations + +* Moved [`mixed_attributes_style`] to `style` (Remains warn-by-default) + [#12572](https://github.com/rust-lang/rust-clippy/pull/12572) + +### Enhancements + +* [`thread_local_initializer_can_be_made_const`]: Now checks the [`msrv`] configuration + [#12405](https://github.com/rust-lang/rust-clippy/pull/12405) +* [`disallowed_macros`]: Code generated by derive macros can no longer allow this lint + [#12267](https://github.com/rust-lang/rust-clippy/pull/12267) +* [`wildcard_imports`]: Add configuration [`allowed-wildcard-imports`] to allow preconfigured wildcards + [#11979](https://github.com/rust-lang/rust-clippy/pull/11979) + +### ICE Fixes + +* [`ptr_as_ptr`]: No longer ICEs on types from other crates + [#12617](https://github.com/rust-lang/rust-clippy/pull/12617) +* [`cast_sign_loss`]: Avoids an infinit loop when casting two changed `.unwrap()` calls + [#12508](https://github.com/rust-lang/rust-clippy/pull/12508) ## Rust 1.77 -Current stable, released 2024-03-18 +Released 2024-03-18 [View all 93 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-12-16T18%3A20%3A00Z..2024-01-25T18%3A15%3A56Z+base%3Amaster) From 71db2d14510d82c2499cf0621279389c7e0f92ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ul=C4=85=C5=BCka=20Mateusz?= Date: Mon, 29 Apr 2024 22:32:36 +0200 Subject: [PATCH 184/279] [type_complexity]: Fix duplicate errors --- clippy_lints/src/types/mod.rs | 12 +++++++++--- tests/ui/type_complexity.rs | 2 -- tests/ui/type_complexity.stderr | 30 +++++++++++++++--------------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 0802cb2b7c75..5e45ab211efd 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -12,8 +12,8 @@ mod vec_box; use rustc_hir as hir; use rustc_hir::intravisit::FnKind; use rustc_hir::{ - Body, FnDecl, FnRetTy, GenericArg, ImplItem, ImplItemKind, Item, ItemKind, LetStmt, MutTy, QPath, TraitItem, - TraitItemKind, TyKind, + Body, FnDecl, FnRetTy, GenericArg, ImplItem, ImplItemKind, Item, ItemKind, LetStmt, MutTy, QPath, TraitFn, + TraitItem, TraitItemKind, TyKind, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; @@ -420,7 +420,13 @@ impl<'tcx> LateLintPass<'tcx> for Types { TraitItemKind::Const(ty, _) | TraitItemKind::Type(_, Some(ty)) => { self.check_ty(cx, ty, context); }, - TraitItemKind::Fn(ref sig, _) => self.check_fn_decl(cx, sig.decl, context), + TraitItemKind::Fn(ref sig, trait_method) => { + // Check only methods without body + // Methods with body are covered by check_fn. + if let TraitFn::Required(_) = trait_method { + self.check_fn_decl(cx, sig.decl, context); + } + }, TraitItemKind::Type(..) => (), } } diff --git a/tests/ui/type_complexity.rs b/tests/ui/type_complexity.rs index b057dc4e89f2..be28ee2da0cd 100644 --- a/tests/ui/type_complexity.rs +++ b/tests/ui/type_complexity.rs @@ -1,5 +1,3 @@ -//@compile-flags: -Zdeduplicate-diagnostics=yes - #![warn(clippy::all)] #![allow(unused, clippy::needless_pass_by_value, clippy::vec_box, clippy::useless_vec)] #![feature(associated_type_defaults)] diff --git a/tests/ui/type_complexity.stderr b/tests/ui/type_complexity.stderr index bfbab8647e85..9e27899e4f90 100644 --- a/tests/ui/type_complexity.stderr +++ b/tests/ui/type_complexity.stderr @@ -1,5 +1,5 @@ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:9:12 + --> tests/ui/type_complexity.rs:7:12 | LL | const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,85 +8,85 @@ LL | const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); = help: to override `-D warnings` add `#[allow(clippy::type_complexity)]` error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:12:12 + --> tests/ui/type_complexity.rs:10:12 | LL | static ST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:16:8 + --> tests/ui/type_complexity.rs:14:8 | LL | f: Vec>>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:20:11 + --> tests/ui/type_complexity.rs:18:11 | LL | struct Ts(Vec>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:24:11 + --> tests/ui/type_complexity.rs:22:11 | LL | Tuple(Vec>>), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:26:17 + --> tests/ui/type_complexity.rs:24:17 | LL | Struct { f: Vec>> }, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:31:14 + --> tests/ui/type_complexity.rs:29:14 | LL | const A: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:33:30 + --> tests/ui/type_complexity.rs:31:30 | LL | fn impl_method(&self, p: Vec>>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:38:14 + --> tests/ui/type_complexity.rs:36:14 | LL | const A: Vec>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:40:14 + --> tests/ui/type_complexity.rs:38:14 | LL | type B = Vec>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:42:25 + --> tests/ui/type_complexity.rs:40:25 | LL | fn method(&self, p: Vec>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:44:29 + --> tests/ui/type_complexity.rs:42:29 | LL | fn def_method(&self, p: Vec>>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:57:15 + --> tests/ui/type_complexity.rs:55:15 | LL | fn test1() -> Vec>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:62:14 + --> tests/ui/type_complexity.rs:60:14 | LL | fn test2(_x: Vec>>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: very complex type used. Consider factoring parts into `type` definitions - --> tests/ui/type_complexity.rs:66:13 + --> tests/ui/type_complexity.rs:64:13 | LL | let _y: Vec>> = vec![]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 21c688af86a52cf5d44c69c274179e7410e01a49 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 26 Apr 2024 21:14:37 +0200 Subject: [PATCH 185/279] Consider inner modules to be local in the `non_local_definitions` lint --- compiler/rustc_lint/src/non_local_def.rs | 16 +++++--- .../ui/lint/non-local-defs/module_as_local.rs | 38 +++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 tests/ui/lint/non-local-defs/module_as_local.rs diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 004c2c2e4f44..3ab15a5be588 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -356,7 +356,7 @@ fn path_has_local_parent( } /// Given a def id and a parent impl def id, this checks if the parent -/// def id correspond to the def id of the parent impl definition. +/// def id (modulo modules) correspond to the def id of the parent impl definition. #[inline] fn did_has_local_parent( did: DefId, @@ -364,8 +364,14 @@ fn did_has_local_parent( impl_parent: DefId, impl_parent_parent: Option, ) -> bool { - did.is_local() && { - let res_parent = tcx.parent(did); - res_parent == impl_parent || Some(res_parent) == impl_parent_parent - } + did.is_local() + && if let Some(did_parent) = tcx.opt_parent(did) { + did_parent == impl_parent + || Some(did_parent) == impl_parent_parent + || !did_parent.is_crate_root() + && tcx.def_kind(did_parent) == DefKind::Mod + && did_has_local_parent(did_parent, tcx, impl_parent, impl_parent_parent) + } else { + false + } } diff --git a/tests/ui/lint/non-local-defs/module_as_local.rs b/tests/ui/lint/non-local-defs/module_as_local.rs new file mode 100644 index 000000000000..bb215026c7d4 --- /dev/null +++ b/tests/ui/lint/non-local-defs/module_as_local.rs @@ -0,0 +1,38 @@ +//! This test checks that module are treated as if they were local +//! +//! https://github.com/rust-lang/rust/issues/124396 + +//@ check-pass + +trait JoinTo {} + +fn simple_one() { + mod posts { + #[allow(non_camel_case_types)] + pub struct table {} + } + + impl JoinTo for posts::table {} +} + +fn simple_two() { + mod posts { + pub mod posts { + #[allow(non_camel_case_types)] + pub struct table {} + } + } + + impl JoinTo for posts::posts::table {} +} + +struct Global; +fn trait_() { + mod posts { + pub trait AdjecentTo {} + } + + impl posts::AdjecentTo for Global {} +} + +fn main() {} From 13825dcc156ee848dcbd57f3c118e864fc158c56 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 29 Apr 2024 11:16:21 -0400 Subject: [PATCH 186/279] Take proof trees by value in inspect goal --- .../rustc_middle/src/traits/solve/inspect.rs | 6 ++--- .../src/solve/inspect/analyse.rs | 27 +++++++++---------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_middle/src/traits/solve/inspect.rs b/compiler/rustc_middle/src/traits/solve/inspect.rs index 0f3ace2d55d3..70d5a0822915 100644 --- a/compiler/rustc_middle/src/traits/solve/inspect.rs +++ b/compiler/rustc_middle/src/traits/solve/inspect.rs @@ -60,14 +60,14 @@ pub struct GoalEvaluation<'tcx> { pub evaluation: CanonicalGoalEvaluation<'tcx>, } -#[derive(Eq, PartialEq)] +#[derive(Eq, PartialEq, Debug)] pub struct CanonicalGoalEvaluation<'tcx> { pub goal: CanonicalInput<'tcx>, pub kind: CanonicalGoalEvaluationKind<'tcx>, pub result: QueryResult<'tcx>, } -#[derive(Eq, PartialEq)] +#[derive(Eq, PartialEq, Debug)] pub enum CanonicalGoalEvaluationKind<'tcx> { Overflow, CycleInStack, @@ -86,7 +86,7 @@ pub struct AddedGoalsEvaluation<'tcx> { pub result: Result, } -#[derive(Eq, PartialEq)] +#[derive(Eq, PartialEq, Debug)] pub struct GoalEvaluationStep<'tcx> { pub instantiated_goal: QueryInput<'tcx, ty::Predicate<'tcx>>, diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 2d58111e8038..45b0e8d2eb26 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -34,9 +34,9 @@ pub struct InspectConfig { pub struct InspectGoal<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, depth: usize, - orig_values: &'a [ty::GenericArg<'tcx>], + orig_values: Vec>, goal: Goal<'tcx, ty::Predicate<'tcx>>, - evaluation: &'a inspect::GoalEvaluation<'tcx>, + evaluation: inspect::CanonicalGoalEvaluation<'tcx>, } pub struct InspectCandidate<'a, 'tcx> { @@ -139,7 +139,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { try_visit!(visitor.visit_goal(&InspectGoal::new( infcx, self.goal.depth + 1, - &proof_tree.unwrap(), + proof_tree.unwrap(), ))); } } @@ -164,7 +164,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { } pub fn result(&self) -> Result { - self.evaluation.evaluation.result.map(|c| c.value.certainty) + self.evaluation.result.map(|c| c.value.certainty) } fn candidates_recur( @@ -221,7 +221,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { pub fn candidates(&'a self) -> Vec> { let mut candidates = vec![]; - let last_eval_step = match self.evaluation.evaluation.kind { + let last_eval_step = match self.evaluation.kind { inspect::CanonicalGoalEvaluationKind::Overflow | inspect::CanonicalGoalEvaluationKind::CycleInStack | inspect::CanonicalGoalEvaluationKind::ProvisionalCacheHit => { @@ -254,18 +254,15 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { candidates.pop().filter(|_| candidates.is_empty()) } - fn new( - infcx: &'a InferCtxt<'tcx>, - depth: usize, - root: &'a inspect::GoalEvaluation<'tcx>, - ) -> Self { - match root.kind { - inspect::GoalEvaluationKind::Root { ref orig_values } => InspectGoal { + fn new(infcx: &'a InferCtxt<'tcx>, depth: usize, root: inspect::GoalEvaluation<'tcx>) -> Self { + let inspect::GoalEvaluation { uncanonicalized_goal, kind, evaluation } = root; + match kind { + inspect::GoalEvaluationKind::Root { orig_values } => InspectGoal { infcx, depth, orig_values, - goal: root.uncanonicalized_goal.fold_with(&mut EagerResolver::new(infcx)), - evaluation: root, + goal: uncanonicalized_goal.fold_with(&mut EagerResolver::new(infcx)), + evaluation, }, inspect::GoalEvaluationKind::Nested { .. } => unreachable!(), } @@ -294,6 +291,6 @@ impl<'tcx> InferCtxt<'tcx> { ) -> V::Result { let (_, proof_tree) = self.evaluate_root_goal(goal, GenerateProofTree::Yes); let proof_tree = proof_tree.unwrap(); - visitor.visit_goal(&InspectGoal::new(self, 0, &proof_tree)) + visitor.visit_goal(&InspectGoal::new(self, 0, proof_tree)) } } From 7597d1504e144e4bbfec9032b7c81e161d5fb1c5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 29 Apr 2024 11:52:51 -0400 Subject: [PATCH 187/279] Split out instantiate_nested_goals --- .../src/solve/inspect/analyse.rs | 79 ++++++++++--------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 45b0e8d2eb26..cba326201758 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -57,6 +57,10 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { self.result.map(|c| c.value.certainty) } + pub fn goal(&self) -> &'a InspectGoal<'a, 'tcx> { + self.goal + } + /// Certainty passed into `evaluate_added_goals_and_make_canonical_response`. /// /// If this certainty is `Yes`, then we must be confident that the candidate @@ -74,46 +78,55 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { /// the state of the `infcx`. pub fn visit_nested_no_probe>(&self, visitor: &mut V) -> V::Result { if self.goal.depth < visitor.config().max_depth { - let infcx = self.goal.infcx; - let param_env = self.goal.goal.param_env; - let mut orig_values = self.goal.orig_values.to_vec(); - let mut instantiated_goals = vec![]; - for goal in &self.nested_goals { - let goal = canonical::instantiate_canonical_state( + for goal in self.instantiate_nested_goals(visitor.span()) { + try_visit!(visitor.visit_goal(&goal)); + } + } + + V::Result::output() + } + + /// Instantiate the nested goals for the candidate without rolling back their + /// inference constraints. This function modifies the state of the `infcx`. + pub fn instantiate_nested_goals(&self, span: Span) -> Vec> { + let infcx = self.goal.infcx; + let param_env = self.goal.goal.param_env; + let mut orig_values = self.goal.orig_values.to_vec(); + let instantiated_goals: Vec<_> = self + .nested_goals + .iter() + .map(|goal| { + canonical::instantiate_canonical_state( infcx, - visitor.span(), + span, param_env, &mut orig_values, *goal, - ); - instantiated_goals.push(goal); - } + ) + }) + .collect(); - let () = canonical::instantiate_canonical_state( - infcx, - visitor.span(), - param_env, - &mut orig_values, - self.final_state, - ); + let () = canonical::instantiate_canonical_state( + infcx, + span, + param_env, + &mut orig_values, + self.final_state, + ); - for &goal in &instantiated_goals { + instantiated_goals + .into_iter() + .map(|goal| { let proof_tree = match goal.predicate.kind().no_bound_vars() { Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => { let unconstrained_term = match term.unpack() { ty::TermKind::Ty(_) => infcx - .next_ty_var(TypeVariableOrigin { - param_def_id: None, - span: visitor.span(), - }) + .next_ty_var(TypeVariableOrigin { param_def_id: None, span }) .into(), ty::TermKind::Const(ct) => infcx .next_const_var( ct.ty(), - ConstVariableOrigin { - param_def_id: None, - span: visitor.span(), - }, + ConstVariableOrigin { param_def_id: None, span }, ) .into(), }; @@ -129,22 +142,16 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { }) .1; let InferOk { value: (), obligations: _ } = infcx - .at(&ObligationCause::dummy(), param_env) + .at(&ObligationCause::dummy_with_span(span), param_env) .eq(DefineOpaqueTypes::Yes, term, unconstrained_term) .unwrap(); proof_tree } _ => infcx.evaluate_root_goal(goal, GenerateProofTree::Yes).1, }; - try_visit!(visitor.visit_goal(&InspectGoal::new( - infcx, - self.goal.depth + 1, - proof_tree.unwrap(), - ))); - } - } - - V::Result::output() + InspectGoal::new(infcx, self.goal.depth + 1, proof_tree.unwrap()) + }) + .collect() } /// Visit all nested goals of this candidate, rolling back From c8079e9390cd278fac3ccbeec4052e6b4e80304d Mon Sep 17 00:00:00 2001 From: "Christopher B. Speir" Date: Mon, 29 Apr 2024 17:22:20 -0500 Subject: [PATCH 188/279] Add diagnostic item for std::iter::Iterator::enumerate --- compiler/rustc_span/src/symbol.rs | 1 + library/core/src/iter/traits/iterator.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 99591b5e1440..6c7aa1ba12ce 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -754,6 +754,7 @@ symbols! { enable, encode, end, + enumerate_method, env, env_CFG_RELEASE: env!("CFG_RELEASE"), eprint_macro, diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 7c1c6122efe4..cee99e28b5a9 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -974,6 +974,7 @@ pub trait Iterator { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_do_not_const_check] + #[cfg_attr(not(test), rustc_diagnostic_item = "enumerate_method")] fn enumerate(self) -> Enumerate where Self: Sized, From 8101884b37473a4aee62dc7553c8f6373d31c5f7 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Mon, 29 Apr 2024 23:54:27 +0000 Subject: [PATCH 189/279] codegen tests: Tolerate `range()` qualifications in enum tests Current LLVM can infer range bounds on the i8s involved with these tests, and annotates it. Accept these bounds if present. --- tests/codegen/enum/enum-match.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/codegen/enum/enum-match.rs b/tests/codegen/enum/enum-match.rs index f1c40f6695be..ced26c0a4340 100644 --- a/tests/codegen/enum/enum-match.rs +++ b/tests/codegen/enum/enum-match.rs @@ -11,7 +11,7 @@ pub enum Enum0 { B, } -// CHECK: define noundef i8 @match0{{.*}} +// CHECK: define noundef{{( range\(i8 [0-9]+, [0-9]+\))?}} i8 @match0{{.*}} // CHECK-NEXT: start: // CHECK-NEXT: %1 = icmp eq i8 %0, 2 // CHECK-NEXT: %2 = and i8 %0, 1 @@ -32,7 +32,7 @@ pub enum Enum1 { C, } -// CHECK: define noundef i8 @match1{{.*}} +// CHECK: define noundef{{( range\(i8 [0-9]+, [0-9]+\))?}} i8 @match1{{.*}} // CHECK-NEXT: start: // CHECK-NEXT: %1 = add i8 %0, -2 // CHECK-NEXT: %2 = zext i8 %1 to i64 @@ -91,7 +91,7 @@ pub enum Enum2 { E, } -// CHECK: define noundef i8 @match2{{.*}} +// CHECK: define noundef{{( range\(i8 [0-9]+, [0-9]+\))?}} i8 @match2{{.*}} // CHECK-NEXT: start: // CHECK-NEXT: %1 = add i8 %0, 2 // CHECK-NEXT: %2 = zext i8 %1 to i64 From 7d1c6af3dc408c1f9811e6bd576804d544bfa90d Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 29 Apr 2024 22:25:09 +1000 Subject: [PATCH 190/279] coverage: Prepare to split `spans.rs` into two files --- .../rustc_mir_transform/src/coverage/mod.rs | 1 - .../rustc_mir_transform/src/coverage/spans.rs | 49 ++++++++++--------- .../src/coverage/spans/from_mir.rs | 2 +- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 159c099fac50..0300232019bc 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -3,7 +3,6 @@ pub mod query; mod counters; mod graph; mod spans; - #[cfg(test)] mod tests; diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index b64b1212cecc..d27ce2fc317a 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -1,12 +1,13 @@ +use std::collections::BTreeSet; + use rustc_data_structures::graph::DirectedGraph; use rustc_index::bit_set::BitSet; use rustc_middle::mir; use rustc_middle::mir::coverage::ConditionInfo; use rustc_span::{BytePos, Span}; -use std::collections::BTreeSet; use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB}; -use crate::coverage::spans::from_mir::SpanFromMir; +use crate::coverage::spans::from_mir::{extract_branch_pairs, extract_mcdc_mappings, SpanFromMir}; use crate::coverage::ExtractedHirInfo; mod from_mir; @@ -91,28 +92,11 @@ pub(super) fn generate_coverage_spans( mappings.push(BcbMapping { kind: BcbMappingKind::Code(START_BCB), span }); } } else { - let sorted_spans = from_mir::mir_to_initial_sorted_coverage_spans( - mir_body, - hir_info, - basic_coverage_blocks, - ); - let coverage_spans = SpansRefiner::refine_sorted_spans(sorted_spans); - mappings.extend(coverage_spans.into_iter().map(|RefinedCovspan { bcb, span, .. }| { - // Each span produced by the generator represents an ordinary code region. - BcbMapping { kind: BcbMappingKind::Code(bcb), span } - })); + extract_refined_covspans(mir_body, hir_info, basic_coverage_blocks, &mut mappings); - branch_pairs.extend(from_mir::extract_branch_pairs( - mir_body, - hir_info, - basic_coverage_blocks, - )); + branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, basic_coverage_blocks)); - mappings.extend(from_mir::extract_mcdc_mappings( - mir_body, - hir_info.body_span, - basic_coverage_blocks, - )); + mappings.extend(extract_mcdc_mappings(mir_body, hir_info.body_span, basic_coverage_blocks)); } if mappings.is_empty() && branch_pairs.is_empty() { @@ -149,6 +133,27 @@ pub(super) fn generate_coverage_spans( Some(CoverageSpans { bcb_has_mappings, mappings, branch_pairs, test_vector_bitmap_bytes }) } +#[allow(unused_imports)] // Remove this line during the actual split. +// FIXME(#124545) It's awkward that we have to re-export this, because it's an +// internal detail of `from_mir` that is also needed when handling branch and +// MC/DC spans. Ideally we would find a more natural home for it. +pub(super) use from_mir::unexpand_into_body_span_with_visible_macro; + +pub(super) fn extract_refined_covspans( + mir_body: &mir::Body<'_>, + hir_info: &ExtractedHirInfo, + basic_coverage_blocks: &CoverageGraph, + mappings: &mut impl Extend, +) { + let sorted_spans = + from_mir::mir_to_initial_sorted_coverage_spans(mir_body, hir_info, basic_coverage_blocks); + let coverage_spans = SpansRefiner::refine_sorted_spans(sorted_spans); + mappings.extend(coverage_spans.into_iter().map(|RefinedCovspan { bcb, span, .. }| { + // Each span produced by the generator represents an ordinary code region. + BcbMapping { kind: BcbMappingKind::Code(bcb), span } + })); +} + #[derive(Debug)] struct CurrCovspan { span: Span, diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs index 142dfc17fb8f..2b1e0b1f4bb5 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs @@ -287,7 +287,7 @@ fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option { /// /// [^1]Expansions result from Rust syntax including macros, syntactic sugar, /// etc.). -fn unexpand_into_body_span_with_visible_macro( +pub(crate) fn unexpand_into_body_span_with_visible_macro( original_span: Span, body_span: Span, ) -> Option<(Span, Option)> { From ba87e5bb3e2d6f086d0f5a6155fffc127be0da4e Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 29 Apr 2024 22:25:09 +1000 Subject: [PATCH 191/279] coverage: Split off `mappings.rs` from `spans.rs` and `from_mir.rs` --- .../src/coverage/mappings.rs | 275 ++++++++++++++++++ .../rustc_mir_transform/src/coverage/mod.rs | 5 +- .../rustc_mir_transform/src/coverage/spans.rs | 132 +-------- .../src/coverage/spans/from_mir.rs | 146 +--------- 4 files changed, 283 insertions(+), 275 deletions(-) create mode 100644 compiler/rustc_mir_transform/src/coverage/mappings.rs diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs new file mode 100644 index 000000000000..d364658efb6d --- /dev/null +++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs @@ -0,0 +1,275 @@ +use std::collections::BTreeSet; + +use rustc_data_structures::graph::DirectedGraph; +use rustc_index::bit_set::BitSet; +use rustc_middle::mir::coverage::{ + BlockMarkerId, BranchSpan, ConditionInfo, CoverageKind, MCDCBranchSpan, MCDCDecisionSpan, +}; +use rustc_middle::mir::{self, BasicBlock, StatementKind}; +use rustc_span::Span; + +use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB}; +use crate::coverage::spans::{ + extract_refined_covspans, unexpand_into_body_span_with_visible_macro, +}; +use crate::coverage::ExtractedHirInfo; +use rustc_index::IndexVec; + +#[derive(Clone, Debug)] +pub(super) enum BcbMappingKind { + /// Associates an ordinary executable code span with its corresponding BCB. + Code(BasicCoverageBlock), + + // Ordinary branch mappings are stored separately, so they don't have a + // variant in this enum. + // + /// Associates a mcdc branch span with condition info besides fields for normal branch. + MCDCBranch { + true_bcb: BasicCoverageBlock, + false_bcb: BasicCoverageBlock, + /// If `None`, this actually represents a normal branch mapping inserted + /// for code that was too complex for MC/DC. + condition_info: Option, + decision_depth: u16, + }, + /// Associates a mcdc decision with its join BCB. + MCDCDecision { + end_bcbs: BTreeSet, + bitmap_idx: u32, + conditions_num: u16, + decision_depth: u16, + }, +} + +#[derive(Debug)] +pub(super) struct BcbMapping { + pub(super) kind: BcbMappingKind, + pub(super) span: Span, +} + +/// This is separate from [`BcbMappingKind`] to help prepare for larger changes +/// that will be needed for improved branch coverage in the future. +/// (See .) +#[derive(Debug)] +pub(super) struct BcbBranchPair { + pub(super) span: Span, + pub(super) true_bcb: BasicCoverageBlock, + pub(super) false_bcb: BasicCoverageBlock, +} + +pub(super) struct CoverageSpans { + bcb_has_mappings: BitSet, + pub(super) mappings: Vec, + pub(super) branch_pairs: Vec, + test_vector_bitmap_bytes: u32, +} + +impl CoverageSpans { + pub(super) fn bcb_has_coverage_spans(&self, bcb: BasicCoverageBlock) -> bool { + self.bcb_has_mappings.contains(bcb) + } + + pub(super) fn test_vector_bitmap_bytes(&self) -> u32 { + self.test_vector_bitmap_bytes + } +} + +/// Extracts coverage-relevant spans from MIR, and associates them with +/// their corresponding BCBs. +/// +/// Returns `None` if no coverage-relevant spans could be extracted. +pub(super) fn generate_coverage_spans( + mir_body: &mir::Body<'_>, + hir_info: &ExtractedHirInfo, + basic_coverage_blocks: &CoverageGraph, +) -> Option { + let mut mappings = vec![]; + let mut branch_pairs = vec![]; + + if hir_info.is_async_fn { + // An async function desugars into a function that returns a future, + // with the user code wrapped in a closure. Any spans in the desugared + // outer function will be unhelpful, so just keep the signature span + // and ignore all of the spans in the MIR body. + if let Some(span) = hir_info.fn_sig_span_extended { + mappings.push(BcbMapping { kind: BcbMappingKind::Code(START_BCB), span }); + } + } else { + extract_refined_covspans(mir_body, hir_info, basic_coverage_blocks, &mut mappings); + + branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, basic_coverage_blocks)); + + mappings.extend(extract_mcdc_mappings(mir_body, hir_info.body_span, basic_coverage_blocks)); + } + + if mappings.is_empty() && branch_pairs.is_empty() { + return None; + } + + // Identify which BCBs have one or more mappings. + let mut bcb_has_mappings = BitSet::new_empty(basic_coverage_blocks.num_nodes()); + let mut insert = |bcb| { + bcb_has_mappings.insert(bcb); + }; + let mut test_vector_bitmap_bytes = 0; + for BcbMapping { kind, span: _ } in &mappings { + match *kind { + BcbMappingKind::Code(bcb) => insert(bcb), + BcbMappingKind::MCDCBranch { true_bcb, false_bcb, .. } => { + insert(true_bcb); + insert(false_bcb); + } + BcbMappingKind::MCDCDecision { bitmap_idx, conditions_num, .. } => { + // `bcb_has_mappings` is used for inject coverage counters + // but they are not needed for decision BCBs. + // While the length of test vector bitmap should be calculated here. + test_vector_bitmap_bytes = test_vector_bitmap_bytes + .max(bitmap_idx + (1_u32 << conditions_num as u32).div_ceil(8)); + } + } + } + for &BcbBranchPair { true_bcb, false_bcb, .. } in &branch_pairs { + insert(true_bcb); + insert(false_bcb); + } + + Some(CoverageSpans { bcb_has_mappings, mappings, branch_pairs, test_vector_bitmap_bytes }) +} + +fn resolve_block_markers( + branch_info: &mir::coverage::BranchInfo, + mir_body: &mir::Body<'_>, +) -> IndexVec> { + let mut block_markers = IndexVec::>::from_elem_n( + None, + branch_info.num_block_markers, + ); + + // Fill out the mapping from block marker IDs to their enclosing blocks. + for (bb, data) in mir_body.basic_blocks.iter_enumerated() { + for statement in &data.statements { + if let StatementKind::Coverage(CoverageKind::BlockMarker { id }) = statement.kind { + block_markers[id] = Some(bb); + } + } + } + + block_markers +} + +// FIXME: There is currently a lot of redundancy between +// `extract_branch_pairs` and `extract_mcdc_mappings`. This is needed so +// that they can each be modified without interfering with the other, but in +// the long term we should try to bring them together again when branch coverage +// and MC/DC coverage support are more mature. + +pub(super) fn extract_branch_pairs( + mir_body: &mir::Body<'_>, + hir_info: &ExtractedHirInfo, + basic_coverage_blocks: &CoverageGraph, +) -> Vec { + let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else { return vec![] }; + + let block_markers = resolve_block_markers(branch_info, mir_body); + + branch_info + .branch_spans + .iter() + .filter_map(|&BranchSpan { span: raw_span, true_marker, false_marker }| { + // For now, ignore any branch span that was introduced by + // expansion. This makes things like assert macros less noisy. + if !raw_span.ctxt().outer_expn_data().is_root() { + return None; + } + let (span, _) = + unexpand_into_body_span_with_visible_macro(raw_span, hir_info.body_span)?; + + let bcb_from_marker = + |marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?); + + let true_bcb = bcb_from_marker(true_marker)?; + let false_bcb = bcb_from_marker(false_marker)?; + + Some(BcbBranchPair { span, true_bcb, false_bcb }) + }) + .collect::>() +} + +pub(super) fn extract_mcdc_mappings( + mir_body: &mir::Body<'_>, + body_span: Span, + basic_coverage_blocks: &CoverageGraph, +) -> Vec { + let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else { + return vec![]; + }; + + let block_markers = resolve_block_markers(branch_info, mir_body); + + let bcb_from_marker = + |marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?); + + let check_branch_bcb = + |raw_span: Span, true_marker: BlockMarkerId, false_marker: BlockMarkerId| { + // For now, ignore any branch span that was introduced by + // expansion. This makes things like assert macros less noisy. + if !raw_span.ctxt().outer_expn_data().is_root() { + return None; + } + let (span, _) = unexpand_into_body_span_with_visible_macro(raw_span, body_span)?; + + let true_bcb = bcb_from_marker(true_marker)?; + let false_bcb = bcb_from_marker(false_marker)?; + Some((span, true_bcb, false_bcb)) + }; + + let mcdc_branch_filter_map = |&MCDCBranchSpan { + span: raw_span, + true_marker, + false_marker, + condition_info, + decision_depth, + }| { + check_branch_bcb(raw_span, true_marker, false_marker).map(|(span, true_bcb, false_bcb)| { + BcbMapping { + kind: BcbMappingKind::MCDCBranch { + true_bcb, + false_bcb, + condition_info, + decision_depth, + }, + span, + } + }) + }; + + let mut next_bitmap_idx = 0; + + let decision_filter_map = |decision: &MCDCDecisionSpan| { + let (span, _) = unexpand_into_body_span_with_visible_macro(decision.span, body_span)?; + + let end_bcbs = decision + .end_markers + .iter() + .map(|&marker| bcb_from_marker(marker)) + .collect::>()?; + + let bitmap_idx = next_bitmap_idx; + next_bitmap_idx += (1_u32 << decision.conditions_num).div_ceil(8); + + Some(BcbMapping { + kind: BcbMappingKind::MCDCDecision { + end_bcbs, + bitmap_idx, + conditions_num: decision.conditions_num as u16, + decision_depth: decision.decision_depth, + }, + span, + }) + }; + + std::iter::empty() + .chain(branch_info.mcdc_branch_spans.iter().filter_map(mcdc_branch_filter_map)) + .chain(branch_info.mcdc_decision_spans.iter().filter_map(decision_filter_map)) + .collect::>() +} diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 0300232019bc..9edde6662469 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -2,13 +2,14 @@ pub mod query; mod counters; mod graph; +mod mappings; mod spans; #[cfg(test)] mod tests; use self::counters::{CounterIncrementSite, CoverageCounters}; use self::graph::{BasicCoverageBlock, CoverageGraph}; -use self::spans::{BcbBranchPair, BcbMapping, BcbMappingKind, CoverageSpans}; +use self::mappings::{BcbBranchPair, BcbMapping, BcbMappingKind, CoverageSpans}; use crate::MirPass; @@ -70,7 +71,7 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir: //////////////////////////////////////////////////// // Compute coverage spans from the `CoverageGraph`. let Some(coverage_spans) = - spans::generate_coverage_spans(mir_body, &hir_info, &basic_coverage_blocks) + mappings::generate_coverage_spans(mir_body, &hir_info, &basic_coverage_blocks) else { // No relevant spans were found in MIR, so skip instrumenting this function. return; diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index d27ce2fc317a..d6432e2e9d41 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -1,139 +1,13 @@ -use std::collections::BTreeSet; - -use rustc_data_structures::graph::DirectedGraph; -use rustc_index::bit_set::BitSet; use rustc_middle::mir; -use rustc_middle::mir::coverage::ConditionInfo; use rustc_span::{BytePos, Span}; -use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB}; -use crate::coverage::spans::from_mir::{extract_branch_pairs, extract_mcdc_mappings, SpanFromMir}; +use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph}; +use crate::coverage::mappings::{BcbMapping, BcbMappingKind}; +use crate::coverage::spans::from_mir::SpanFromMir; use crate::coverage::ExtractedHirInfo; mod from_mir; -#[derive(Clone, Debug)] -pub(super) enum BcbMappingKind { - /// Associates an ordinary executable code span with its corresponding BCB. - Code(BasicCoverageBlock), - - // Ordinary branch mappings are stored separately, so they don't have a - // variant in this enum. - // - /// Associates a mcdc branch span with condition info besides fields for normal branch. - MCDCBranch { - true_bcb: BasicCoverageBlock, - false_bcb: BasicCoverageBlock, - /// If `None`, this actually represents a normal branch mapping inserted - /// for code that was too complex for MC/DC. - condition_info: Option, - decision_depth: u16, - }, - /// Associates a mcdc decision with its join BCB. - MCDCDecision { - end_bcbs: BTreeSet, - bitmap_idx: u32, - conditions_num: u16, - decision_depth: u16, - }, -} - -#[derive(Debug)] -pub(super) struct BcbMapping { - pub(super) kind: BcbMappingKind, - pub(super) span: Span, -} - -/// This is separate from [`BcbMappingKind`] to help prepare for larger changes -/// that will be needed for improved branch coverage in the future. -/// (See .) -#[derive(Debug)] -pub(super) struct BcbBranchPair { - pub(super) span: Span, - pub(super) true_bcb: BasicCoverageBlock, - pub(super) false_bcb: BasicCoverageBlock, -} - -pub(super) struct CoverageSpans { - bcb_has_mappings: BitSet, - pub(super) mappings: Vec, - pub(super) branch_pairs: Vec, - test_vector_bitmap_bytes: u32, -} - -impl CoverageSpans { - pub(super) fn bcb_has_coverage_spans(&self, bcb: BasicCoverageBlock) -> bool { - self.bcb_has_mappings.contains(bcb) - } - - pub(super) fn test_vector_bitmap_bytes(&self) -> u32 { - self.test_vector_bitmap_bytes - } -} - -/// Extracts coverage-relevant spans from MIR, and associates them with -/// their corresponding BCBs. -/// -/// Returns `None` if no coverage-relevant spans could be extracted. -pub(super) fn generate_coverage_spans( - mir_body: &mir::Body<'_>, - hir_info: &ExtractedHirInfo, - basic_coverage_blocks: &CoverageGraph, -) -> Option { - let mut mappings = vec![]; - let mut branch_pairs = vec![]; - - if hir_info.is_async_fn { - // An async function desugars into a function that returns a future, - // with the user code wrapped in a closure. Any spans in the desugared - // outer function will be unhelpful, so just keep the signature span - // and ignore all of the spans in the MIR body. - if let Some(span) = hir_info.fn_sig_span_extended { - mappings.push(BcbMapping { kind: BcbMappingKind::Code(START_BCB), span }); - } - } else { - extract_refined_covspans(mir_body, hir_info, basic_coverage_blocks, &mut mappings); - - branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, basic_coverage_blocks)); - - mappings.extend(extract_mcdc_mappings(mir_body, hir_info.body_span, basic_coverage_blocks)); - } - - if mappings.is_empty() && branch_pairs.is_empty() { - return None; - } - - // Identify which BCBs have one or more mappings. - let mut bcb_has_mappings = BitSet::new_empty(basic_coverage_blocks.num_nodes()); - let mut insert = |bcb| { - bcb_has_mappings.insert(bcb); - }; - let mut test_vector_bitmap_bytes = 0; - for BcbMapping { kind, span: _ } in &mappings { - match *kind { - BcbMappingKind::Code(bcb) => insert(bcb), - BcbMappingKind::MCDCBranch { true_bcb, false_bcb, .. } => { - insert(true_bcb); - insert(false_bcb); - } - BcbMappingKind::MCDCDecision { bitmap_idx, conditions_num, .. } => { - // `bcb_has_mappings` is used for inject coverage counters - // but they are not needed for decision BCBs. - // While the length of test vector bitmap should be calculated here. - test_vector_bitmap_bytes = test_vector_bitmap_bytes - .max(bitmap_idx + (1_u32 << conditions_num as u32).div_ceil(8)); - } - } - } - for &BcbBranchPair { true_bcb, false_bcb, .. } in &branch_pairs { - insert(true_bcb); - insert(false_bcb); - } - - Some(CoverageSpans { bcb_has_mappings, mappings, branch_pairs, test_vector_bitmap_bytes }) -} - -#[allow(unused_imports)] // Remove this line during the actual split. // FIXME(#124545) It's awkward that we have to re-export this, because it's an // internal detail of `from_mir` that is also needed when handling branch and // MC/DC spans. Ideally we would find a more natural home for it. diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs index 2b1e0b1f4bb5..4ce37b5defce 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs @@ -1,11 +1,8 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; -use rustc_index::IndexVec; -use rustc_middle::mir::coverage::{ - BlockMarkerId, BranchSpan, CoverageKind, MCDCBranchSpan, MCDCDecisionSpan, -}; +use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::mir::{ - self, AggregateKind, BasicBlock, FakeReadCause, Rvalue, Statement, StatementKind, Terminator, + self, AggregateKind, FakeReadCause, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; use rustc_span::{ExpnKind, MacroKind, Span, Symbol}; @@ -13,7 +10,6 @@ use rustc_span::{ExpnKind, MacroKind, Span, Symbol}; use crate::coverage::graph::{ BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB, }; -use crate::coverage::spans::{BcbBranchPair, BcbMapping, BcbMappingKind}; use crate::coverage::ExtractedHirInfo; /// Traverses the MIR body to produce an initial collection of coverage-relevant @@ -365,141 +361,3 @@ impl SpanFromMir { Self { span, visible_macro, bcb, is_hole } } } - -fn resolve_block_markers( - branch_info: &mir::coverage::BranchInfo, - mir_body: &mir::Body<'_>, -) -> IndexVec> { - let mut block_markers = IndexVec::>::from_elem_n( - None, - branch_info.num_block_markers, - ); - - // Fill out the mapping from block marker IDs to their enclosing blocks. - for (bb, data) in mir_body.basic_blocks.iter_enumerated() { - for statement in &data.statements { - if let StatementKind::Coverage(CoverageKind::BlockMarker { id }) = statement.kind { - block_markers[id] = Some(bb); - } - } - } - - block_markers -} - -// FIXME: There is currently a lot of redundancy between -// `extract_branch_pairs` and `extract_mcdc_mappings`. This is needed so -// that they can each be modified without interfering with the other, but in -// the long term we should try to bring them together again when branch coverage -// and MC/DC coverage support are more mature. - -pub(super) fn extract_branch_pairs( - mir_body: &mir::Body<'_>, - hir_info: &ExtractedHirInfo, - basic_coverage_blocks: &CoverageGraph, -) -> Vec { - let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else { return vec![] }; - - let block_markers = resolve_block_markers(branch_info, mir_body); - - branch_info - .branch_spans - .iter() - .filter_map(|&BranchSpan { span: raw_span, true_marker, false_marker }| { - // For now, ignore any branch span that was introduced by - // expansion. This makes things like assert macros less noisy. - if !raw_span.ctxt().outer_expn_data().is_root() { - return None; - } - let (span, _) = - unexpand_into_body_span_with_visible_macro(raw_span, hir_info.body_span)?; - - let bcb_from_marker = - |marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?); - - let true_bcb = bcb_from_marker(true_marker)?; - let false_bcb = bcb_from_marker(false_marker)?; - - Some(BcbBranchPair { span, true_bcb, false_bcb }) - }) - .collect::>() -} - -pub(super) fn extract_mcdc_mappings( - mir_body: &mir::Body<'_>, - body_span: Span, - basic_coverage_blocks: &CoverageGraph, -) -> Vec { - let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else { - return vec![]; - }; - - let block_markers = resolve_block_markers(branch_info, mir_body); - - let bcb_from_marker = - |marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?); - - let check_branch_bcb = - |raw_span: Span, true_marker: BlockMarkerId, false_marker: BlockMarkerId| { - // For now, ignore any branch span that was introduced by - // expansion. This makes things like assert macros less noisy. - if !raw_span.ctxt().outer_expn_data().is_root() { - return None; - } - let (span, _) = unexpand_into_body_span_with_visible_macro(raw_span, body_span)?; - - let true_bcb = bcb_from_marker(true_marker)?; - let false_bcb = bcb_from_marker(false_marker)?; - Some((span, true_bcb, false_bcb)) - }; - - let mcdc_branch_filter_map = |&MCDCBranchSpan { - span: raw_span, - true_marker, - false_marker, - condition_info, - decision_depth, - }| { - check_branch_bcb(raw_span, true_marker, false_marker).map(|(span, true_bcb, false_bcb)| { - BcbMapping { - kind: BcbMappingKind::MCDCBranch { - true_bcb, - false_bcb, - condition_info, - decision_depth, - }, - span, - } - }) - }; - - let mut next_bitmap_idx = 0; - - let decision_filter_map = |decision: &MCDCDecisionSpan| { - let (span, _) = unexpand_into_body_span_with_visible_macro(decision.span, body_span)?; - - let end_bcbs = decision - .end_markers - .iter() - .map(|&marker| bcb_from_marker(marker)) - .collect::>()?; - - let bitmap_idx = next_bitmap_idx; - next_bitmap_idx += (1_u32 << decision.conditions_num).div_ceil(8); - - Some(BcbMapping { - kind: BcbMappingKind::MCDCDecision { - end_bcbs, - bitmap_idx, - conditions_num: decision.conditions_num as u16, - decision_depth: decision.decision_depth, - }, - span, - }) - }; - - std::iter::empty() - .chain(branch_info.mcdc_branch_spans.iter().filter_map(mcdc_branch_filter_map)) - .chain(branch_info.mcdc_decision_spans.iter().filter_map(decision_filter_map)) - .collect::>() -} From a76e250abdc5a3e1929334a33655f0393f31183d Mon Sep 17 00:00:00 2001 From: zhuyunxing Date: Tue, 30 Apr 2024 10:05:50 +0800 Subject: [PATCH 192/279] coverage. Add BlockMarkerGen to avoid ownership gymnastics --- .../rustc_mir_build/src/build/coverageinfo.rs | 64 ++++++++++--------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/coverageinfo.rs b/compiler/rustc_mir_build/src/build/coverageinfo.rs index a1c20fcfd836..e3929f105342 100644 --- a/compiler/rustc_mir_build/src/build/coverageinfo.rs +++ b/compiler/rustc_mir_build/src/build/coverageinfo.rs @@ -20,7 +20,7 @@ pub(crate) struct BranchInfoBuilder { /// Maps condition expressions to their enclosing `!`, for better instrumentation. nots: FxHashMap, - num_block_markers: usize, + markers: BlockMarkerGen, branch_spans: Vec, mcdc_branch_spans: Vec, @@ -38,6 +38,35 @@ struct NotInfo { is_flipped: bool, } +#[derive(Default)] +struct BlockMarkerGen { + num_block_markers: usize, +} + +impl BlockMarkerGen { + fn next_block_marker_id(&mut self) -> BlockMarkerId { + let id = BlockMarkerId::from_usize(self.num_block_markers); + self.num_block_markers += 1; + id + } + + fn inject_block_marker( + &mut self, + cfg: &mut CFG<'_>, + source_info: SourceInfo, + block: BasicBlock, + ) -> BlockMarkerId { + let id = self.next_block_marker_id(); + let marker_statement = mir::Statement { + source_info, + kind: mir::StatementKind::Coverage(CoverageKind::BlockMarker { id }), + }; + cfg.push(block, marker_statement); + + id + } +} + impl BranchInfoBuilder { /// Creates a new branch info builder, but only if branch coverage instrumentation /// is enabled and `def_id` represents a function that is eligible for coverage. @@ -45,7 +74,7 @@ impl BranchInfoBuilder { if tcx.sess.instrument_coverage_branch() && tcx.is_eligible_for_coverage(def_id) { Some(Self { nots: FxHashMap::default(), - num_block_markers: 0, + markers: BlockMarkerGen::default(), branch_spans: vec![], mcdc_branch_spans: vec![], mcdc_decision_spans: vec![], @@ -145,39 +174,16 @@ impl BranchInfoBuilder { true_block: BasicBlock, false_block: BasicBlock, ) { - let true_marker = self.inject_block_marker(cfg, source_info, true_block); - let false_marker = self.inject_block_marker(cfg, source_info, false_block); + let true_marker = self.markers.inject_block_marker(cfg, source_info, true_block); + let false_marker = self.markers.inject_block_marker(cfg, source_info, false_block); self.branch_spans.push(BranchSpan { span: source_info.span, true_marker, false_marker }); } - fn next_block_marker_id(&mut self) -> BlockMarkerId { - let id = BlockMarkerId::from_usize(self.num_block_markers); - self.num_block_markers += 1; - id - } - - fn inject_block_marker( - &mut self, - cfg: &mut CFG<'_>, - source_info: SourceInfo, - block: BasicBlock, - ) -> BlockMarkerId { - let id = self.next_block_marker_id(); - - let marker_statement = mir::Statement { - source_info, - kind: mir::StatementKind::Coverage(CoverageKind::BlockMarker { id }), - }; - cfg.push(block, marker_statement); - - id - } - pub(crate) fn into_done(self) -> Option> { let Self { nots: _, - num_block_markers, + markers: BlockMarkerGen { num_block_markers }, branch_spans, mcdc_branch_spans, mcdc_decision_spans, @@ -386,7 +392,7 @@ impl Builder<'_, '_> { // Separate path for handling branches when MC/DC is enabled. if branch_info.mcdc_state.is_some() { let mut inject_block_marker = - |block| branch_info.inject_block_marker(&mut self.cfg, source_info, block); + |block| branch_info.markers.inject_block_marker(&mut self.cfg, source_info, block); let true_marker = inject_block_marker(then_block); let false_marker = inject_block_marker(else_block); let (decision_depth, condition_info) = branch_info From e198c51f16e5ed8480bee455c3a85071cd64d947 Mon Sep 17 00:00:00 2001 From: zhuyunxing Date: Tue, 30 Apr 2024 10:21:46 +0800 Subject: [PATCH 193/279] coverage. Add MCDCInfoBuilder to isolate all mcdc stuff from BranchInfoBuilder --- .../rustc_mir_build/src/build/coverageinfo.rs | 196 ++++++++++-------- 1 file changed, 110 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/coverageinfo.rs b/compiler/rustc_mir_build/src/build/coverageinfo.rs index e3929f105342..f0c0abfccec6 100644 --- a/compiler/rustc_mir_build/src/build/coverageinfo.rs +++ b/compiler/rustc_mir_build/src/build/coverageinfo.rs @@ -23,9 +23,7 @@ pub(crate) struct BranchInfoBuilder { markers: BlockMarkerGen, branch_spans: Vec, - mcdc_branch_spans: Vec, - mcdc_decision_spans: Vec, - mcdc_state: Option, + mcdc_info: Option, } #[derive(Clone, Copy)] @@ -76,9 +74,7 @@ impl BranchInfoBuilder { nots: FxHashMap::default(), markers: BlockMarkerGen::default(), branch_spans: vec![], - mcdc_branch_spans: vec![], - mcdc_decision_spans: vec![], - mcdc_state: MCDCState::new_if_enabled(tcx), + mcdc_info: tcx.sess.instrument_coverage_mcdc().then(MCDCInfoBuilder::new), }) } else { None @@ -125,48 +121,6 @@ impl BranchInfoBuilder { } } - fn fetch_mcdc_condition_info( - &mut self, - tcx: TyCtxt<'_>, - true_marker: BlockMarkerId, - false_marker: BlockMarkerId, - ) -> Option<(u16, ConditionInfo)> { - let mcdc_state = self.mcdc_state.as_mut()?; - let decision_depth = mcdc_state.decision_depth(); - let (mut condition_info, decision_result) = - mcdc_state.take_condition(true_marker, false_marker); - // take_condition() returns Some for decision_result when the decision stack - // is empty, i.e. when all the conditions of the decision were instrumented, - // and the decision is "complete". - if let Some(decision) = decision_result { - match decision.conditions_num { - 0 => { - unreachable!("Decision with no condition is not expected"); - } - 1..=MAX_CONDITIONS_NUM_IN_DECISION => { - self.mcdc_decision_spans.push(decision); - } - _ => { - // Do not generate mcdc mappings and statements for decisions with too many conditions. - let rebase_idx = self.mcdc_branch_spans.len() - decision.conditions_num + 1; - for branch in &mut self.mcdc_branch_spans[rebase_idx..] { - branch.condition_info = None; - } - - // ConditionInfo of this branch shall also be reset. - condition_info = None; - - tcx.dcx().emit_warn(MCDCExceedsConditionNumLimit { - span: decision.span, - conditions_num: decision.conditions_num, - max_conditions_num: MAX_CONDITIONS_NUM_IN_DECISION, - }); - } - } - } - condition_info.map(|cond_info| (decision_depth, cond_info)) - } - fn add_two_way_branch<'tcx>( &mut self, cfg: &mut CFG<'tcx>, @@ -185,9 +139,7 @@ impl BranchInfoBuilder { nots: _, markers: BlockMarkerGen { num_block_markers }, branch_spans, - mcdc_branch_spans, - mcdc_decision_spans, - mcdc_state: _, + mcdc_info, } = self; if num_block_markers == 0 { @@ -195,6 +147,9 @@ impl BranchInfoBuilder { return None; } + let (mcdc_decision_spans, mcdc_branch_spans) = + mcdc_info.map(MCDCInfoBuilder::into_done).unwrap_or_default(); + Some(Box::new(mir::coverage::BranchInfo { num_block_markers, branch_spans, @@ -221,20 +176,23 @@ struct MCDCState { } impl MCDCState { - fn new_if_enabled(tcx: TyCtxt<'_>) -> Option { - tcx.sess - .instrument_coverage_mcdc() - .then(|| Self { decision_ctx_stack: vec![MCDCDecisionCtx::default()] }) + fn new() -> Self { + Self { decision_ctx_stack: vec![MCDCDecisionCtx::default()] } } /// Decision depth is given as a u16 to reduce the size of the `CoverageKind`, /// as it is very unlikely that the depth ever reaches 2^16. #[inline] fn decision_depth(&self) -> u16 { - u16::try_from( - self.decision_ctx_stack.len().checked_sub(1).expect("Unexpected empty decision stack"), - ) - .expect("decision depth did not fit in u16, this is likely to be an instrumentation error") + match u16::try_from(self.decision_ctx_stack.len()) + .expect( + "decision depth did not fit in u16, this is likely to be an instrumentation error", + ) + .checked_sub(1) + { + Some(d) => d, + None => bug!("Unexpected empty decision stack"), + } } // At first we assign ConditionIds for each sub expression. @@ -279,8 +237,9 @@ impl MCDCState { // - If the op is OR, the "true_next" of LHS and RHS should be the parent's "true_next". While "false_next" of the LHS is the RHS, the "false next" of RHS is the parent's "false_next". fn record_conditions(&mut self, op: LogicalOp, span: Span) { let decision_depth = self.decision_depth(); - let decision_ctx = - self.decision_ctx_stack.last_mut().expect("Unexpected empty decision_ctx_stack"); + let Some(decision_ctx) = self.decision_ctx_stack.last_mut() else { + bug!("Unexpected empty decision_ctx_stack") + }; let decision = match decision_ctx.processing_decision.as_mut() { Some(decision) => { decision.span = decision.span.to(span); @@ -343,8 +302,9 @@ impl MCDCState { true_marker: BlockMarkerId, false_marker: BlockMarkerId, ) -> (Option, Option) { - let decision_ctx = - self.decision_ctx_stack.last_mut().expect("Unexpected empty decision_ctx_stack"); + let Some(decision_ctx) = self.decision_ctx_stack.last_mut() else { + bug!("Unexpected empty decision_ctx_stack") + }; let Some(condition_info) = decision_ctx.decision_stack.pop_back() else { return (None, None); }; @@ -366,6 +326,74 @@ impl MCDCState { } } +struct MCDCInfoBuilder { + branch_spans: Vec, + decision_spans: Vec, + state: MCDCState, +} + +impl MCDCInfoBuilder { + fn new() -> Self { + Self { branch_spans: vec![], decision_spans: vec![], state: MCDCState::new() } + } + + fn visit_evaluated_condition( + &mut self, + tcx: TyCtxt<'_>, + source_info: SourceInfo, + true_block: BasicBlock, + false_block: BasicBlock, + mut inject_block_marker: impl FnMut(SourceInfo, BasicBlock) -> BlockMarkerId, + ) { + let true_marker = inject_block_marker(source_info, true_block); + let false_marker = inject_block_marker(source_info, false_block); + + let decision_depth = self.state.decision_depth(); + let (mut condition_info, decision_result) = + self.state.take_condition(true_marker, false_marker); + // take_condition() returns Some for decision_result when the decision stack + // is empty, i.e. when all the conditions of the decision were instrumented, + // and the decision is "complete". + if let Some(decision) = decision_result { + match decision.conditions_num { + 0 => { + unreachable!("Decision with no condition is not expected"); + } + 1..=MAX_CONDITIONS_NUM_IN_DECISION => { + self.decision_spans.push(decision); + } + _ => { + // Do not generate mcdc mappings and statements for decisions with too many conditions. + let rebase_idx = self.branch_spans.len() - decision.conditions_num + 1; + for branch in &mut self.branch_spans[rebase_idx..] { + branch.condition_info = None; + } + + // ConditionInfo of this branch shall also be reset. + condition_info = None; + + tcx.dcx().emit_warn(MCDCExceedsConditionNumLimit { + span: decision.span, + conditions_num: decision.conditions_num, + max_conditions_num: MAX_CONDITIONS_NUM_IN_DECISION, + }); + } + } + } + self.branch_spans.push(MCDCBranchSpan { + span: source_info.span, + condition_info, + true_marker, + false_marker, + decision_depth, + }); + } + + fn into_done(self) -> (Vec, Vec) { + (self.decision_spans, self.branch_spans) + } +} + impl Builder<'_, '_> { /// If branch coverage is enabled, inject marker statements into `then_block` /// and `else_block`, and record their IDs in the table of branch spans. @@ -390,23 +418,17 @@ impl Builder<'_, '_> { let source_info = SourceInfo { span: self.thir[expr_id].span, scope: self.source_scope }; // Separate path for handling branches when MC/DC is enabled. - if branch_info.mcdc_state.is_some() { - let mut inject_block_marker = - |block| branch_info.markers.inject_block_marker(&mut self.cfg, source_info, block); - let true_marker = inject_block_marker(then_block); - let false_marker = inject_block_marker(else_block); - let (decision_depth, condition_info) = branch_info - .fetch_mcdc_condition_info(self.tcx, true_marker, false_marker) - .map_or((0, None), |(decision_depth, condition_info)| { - (decision_depth, Some(condition_info)) - }); - branch_info.mcdc_branch_spans.push(MCDCBranchSpan { - span: source_info.span, - condition_info, - true_marker, - false_marker, - decision_depth, - }); + if let Some(mcdc_info) = branch_info.mcdc_info.as_mut() { + let inject_block_marker = |source_info, block| { + branch_info.markers.inject_block_marker(&mut self.cfg, source_info, block) + }; + mcdc_info.visit_evaluated_condition( + self.tcx, + source_info, + then_block, + else_block, + inject_block_marker, + ); return; } @@ -415,25 +437,27 @@ impl Builder<'_, '_> { pub(crate) fn visit_coverage_branch_operation(&mut self, logical_op: LogicalOp, span: Span) { if let Some(branch_info) = self.coverage_branch_info.as_mut() - && let Some(mcdc_state) = branch_info.mcdc_state.as_mut() + && let Some(mcdc_info) = branch_info.mcdc_info.as_mut() { - mcdc_state.record_conditions(logical_op, span); + mcdc_info.state.record_conditions(logical_op, span); } } pub(crate) fn mcdc_increment_depth_if_enabled(&mut self) { if let Some(branch_info) = self.coverage_branch_info.as_mut() - && let Some(mcdc_state) = branch_info.mcdc_state.as_mut() + && let Some(mcdc_info) = branch_info.mcdc_info.as_mut() { - mcdc_state.decision_ctx_stack.push(MCDCDecisionCtx::default()); + mcdc_info.state.decision_ctx_stack.push(MCDCDecisionCtx::default()); }; } pub(crate) fn mcdc_decrement_depth_if_enabled(&mut self) { if let Some(branch_info) = self.coverage_branch_info.as_mut() - && let Some(mcdc_state) = branch_info.mcdc_state.as_mut() + && let Some(mcdc_info) = branch_info.mcdc_info.as_mut() { - mcdc_state.decision_ctx_stack.pop().expect("Unexpected empty decision stack"); + if mcdc_info.state.decision_ctx_stack.pop().is_none() { + bug!("Unexpected empty decision stack"); + } }; } } From 6c8b492f02733120a05b257033db849a2a82c5f4 Mon Sep 17 00:00:00 2001 From: zhuyunxing Date: Tue, 30 Apr 2024 10:25:54 +0800 Subject: [PATCH 194/279] coverage. Split mcdc builder to a sub module of coverageinfo --- .../rustc_mir_build/src/build/coverageinfo.rs | 273 +---------------- .../src/build/coverageinfo/mcdc.rs | 275 ++++++++++++++++++ 2 files changed, 279 insertions(+), 269 deletions(-) create mode 100644 compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs diff --git a/compiler/rustc_mir_build/src/build/coverageinfo.rs b/compiler/rustc_mir_build/src/build/coverageinfo.rs index f0c0abfccec6..e2a5f97a8474 100644 --- a/compiler/rustc_mir_build/src/build/coverageinfo.rs +++ b/compiler/rustc_mir_build/src/build/coverageinfo.rs @@ -1,20 +1,16 @@ +mod mcdc; use std::assert_matches::assert_matches; use std::collections::hash_map::Entry; -use std::collections::VecDeque; use rustc_data_structures::fx::FxHashMap; -use rustc_middle::mir::coverage::{ - BlockMarkerId, BranchSpan, ConditionId, ConditionInfo, CoverageKind, MCDCBranchSpan, - MCDCDecisionSpan, -}; +use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, CoverageKind}; use rustc_middle::mir::{self, BasicBlock, SourceInfo, UnOp}; -use rustc_middle::thir::{ExprId, ExprKind, LogicalOp, Thir}; +use rustc_middle::thir::{ExprId, ExprKind, Thir}; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::LocalDefId; -use rustc_span::Span; +use crate::build::coverageinfo::mcdc::MCDCInfoBuilder; use crate::build::{Builder, CFG}; -use crate::errors::MCDCExceedsConditionNumLimit; pub(crate) struct BranchInfoBuilder { /// Maps condition expressions to their enclosing `!`, for better instrumentation. @@ -159,241 +155,6 @@ impl BranchInfoBuilder { } } -/// The MCDC bitmap scales exponentially (2^n) based on the number of conditions seen, -/// So llvm sets a maximum value prevents the bitmap footprint from growing too large without the user's knowledge. -/// This limit may be relaxed if the [upstream change](https://github.com/llvm/llvm-project/pull/82448) is merged. -const MAX_CONDITIONS_NUM_IN_DECISION: usize = 6; - -#[derive(Default)] -struct MCDCDecisionCtx { - /// To construct condition evaluation tree. - decision_stack: VecDeque, - processing_decision: Option, -} - -struct MCDCState { - decision_ctx_stack: Vec, -} - -impl MCDCState { - fn new() -> Self { - Self { decision_ctx_stack: vec![MCDCDecisionCtx::default()] } - } - - /// Decision depth is given as a u16 to reduce the size of the `CoverageKind`, - /// as it is very unlikely that the depth ever reaches 2^16. - #[inline] - fn decision_depth(&self) -> u16 { - match u16::try_from(self.decision_ctx_stack.len()) - .expect( - "decision depth did not fit in u16, this is likely to be an instrumentation error", - ) - .checked_sub(1) - { - Some(d) => d, - None => bug!("Unexpected empty decision stack"), - } - } - - // At first we assign ConditionIds for each sub expression. - // If the sub expression is composite, re-assign its ConditionId to its LHS and generate a new ConditionId for its RHS. - // - // Example: "x = (A && B) || (C && D) || (D && F)" - // - // Visit Depth1: - // (A && B) || (C && D) || (D && F) - // ^-------LHS--------^ ^-RHS--^ - // ID=1 ID=2 - // - // Visit LHS-Depth2: - // (A && B) || (C && D) - // ^-LHS--^ ^-RHS--^ - // ID=1 ID=3 - // - // Visit LHS-Depth3: - // (A && B) - // LHS RHS - // ID=1 ID=4 - // - // Visit RHS-Depth3: - // (C && D) - // LHS RHS - // ID=3 ID=5 - // - // Visit RHS-Depth2: (D && F) - // LHS RHS - // ID=2 ID=6 - // - // Visit Depth1: - // (A && B) || (C && D) || (D && F) - // ID=1 ID=4 ID=3 ID=5 ID=2 ID=6 - // - // A node ID of '0' always means MC/DC isn't being tracked. - // - // If a "next" node ID is '0', it means it's the end of the test vector. - // - // As the compiler tracks expression in pre-order, we can ensure that condition info of parents are always properly assigned when their children are visited. - // - If the op is AND, the "false_next" of LHS and RHS should be the parent's "false_next". While "true_next" of the LHS is the RHS, the "true next" of RHS is the parent's "true_next". - // - If the op is OR, the "true_next" of LHS and RHS should be the parent's "true_next". While "false_next" of the LHS is the RHS, the "false next" of RHS is the parent's "false_next". - fn record_conditions(&mut self, op: LogicalOp, span: Span) { - let decision_depth = self.decision_depth(); - let Some(decision_ctx) = self.decision_ctx_stack.last_mut() else { - bug!("Unexpected empty decision_ctx_stack") - }; - let decision = match decision_ctx.processing_decision.as_mut() { - Some(decision) => { - decision.span = decision.span.to(span); - decision - } - None => decision_ctx.processing_decision.insert(MCDCDecisionSpan { - span, - conditions_num: 0, - end_markers: vec![], - decision_depth, - }), - }; - - let parent_condition = decision_ctx.decision_stack.pop_back().unwrap_or_default(); - let lhs_id = if parent_condition.condition_id == ConditionId::NONE { - decision.conditions_num += 1; - ConditionId::from(decision.conditions_num) - } else { - parent_condition.condition_id - }; - - decision.conditions_num += 1; - let rhs_condition_id = ConditionId::from(decision.conditions_num); - - let (lhs, rhs) = match op { - LogicalOp::And => { - let lhs = ConditionInfo { - condition_id: lhs_id, - true_next_id: rhs_condition_id, - false_next_id: parent_condition.false_next_id, - }; - let rhs = ConditionInfo { - condition_id: rhs_condition_id, - true_next_id: parent_condition.true_next_id, - false_next_id: parent_condition.false_next_id, - }; - (lhs, rhs) - } - LogicalOp::Or => { - let lhs = ConditionInfo { - condition_id: lhs_id, - true_next_id: parent_condition.true_next_id, - false_next_id: rhs_condition_id, - }; - let rhs = ConditionInfo { - condition_id: rhs_condition_id, - true_next_id: parent_condition.true_next_id, - false_next_id: parent_condition.false_next_id, - }; - (lhs, rhs) - } - }; - // We visit expressions tree in pre-order, so place the left-hand side on the top. - decision_ctx.decision_stack.push_back(rhs); - decision_ctx.decision_stack.push_back(lhs); - } - - fn take_condition( - &mut self, - true_marker: BlockMarkerId, - false_marker: BlockMarkerId, - ) -> (Option, Option) { - let Some(decision_ctx) = self.decision_ctx_stack.last_mut() else { - bug!("Unexpected empty decision_ctx_stack") - }; - let Some(condition_info) = decision_ctx.decision_stack.pop_back() else { - return (None, None); - }; - let Some(decision) = decision_ctx.processing_decision.as_mut() else { - bug!("Processing decision should have been created before any conditions are taken"); - }; - if condition_info.true_next_id == ConditionId::NONE { - decision.end_markers.push(true_marker); - } - if condition_info.false_next_id == ConditionId::NONE { - decision.end_markers.push(false_marker); - } - - if decision_ctx.decision_stack.is_empty() { - (Some(condition_info), decision_ctx.processing_decision.take()) - } else { - (Some(condition_info), None) - } - } -} - -struct MCDCInfoBuilder { - branch_spans: Vec, - decision_spans: Vec, - state: MCDCState, -} - -impl MCDCInfoBuilder { - fn new() -> Self { - Self { branch_spans: vec![], decision_spans: vec![], state: MCDCState::new() } - } - - fn visit_evaluated_condition( - &mut self, - tcx: TyCtxt<'_>, - source_info: SourceInfo, - true_block: BasicBlock, - false_block: BasicBlock, - mut inject_block_marker: impl FnMut(SourceInfo, BasicBlock) -> BlockMarkerId, - ) { - let true_marker = inject_block_marker(source_info, true_block); - let false_marker = inject_block_marker(source_info, false_block); - - let decision_depth = self.state.decision_depth(); - let (mut condition_info, decision_result) = - self.state.take_condition(true_marker, false_marker); - // take_condition() returns Some for decision_result when the decision stack - // is empty, i.e. when all the conditions of the decision were instrumented, - // and the decision is "complete". - if let Some(decision) = decision_result { - match decision.conditions_num { - 0 => { - unreachable!("Decision with no condition is not expected"); - } - 1..=MAX_CONDITIONS_NUM_IN_DECISION => { - self.decision_spans.push(decision); - } - _ => { - // Do not generate mcdc mappings and statements for decisions with too many conditions. - let rebase_idx = self.branch_spans.len() - decision.conditions_num + 1; - for branch in &mut self.branch_spans[rebase_idx..] { - branch.condition_info = None; - } - - // ConditionInfo of this branch shall also be reset. - condition_info = None; - - tcx.dcx().emit_warn(MCDCExceedsConditionNumLimit { - span: decision.span, - conditions_num: decision.conditions_num, - max_conditions_num: MAX_CONDITIONS_NUM_IN_DECISION, - }); - } - } - } - self.branch_spans.push(MCDCBranchSpan { - span: source_info.span, - condition_info, - true_marker, - false_marker, - decision_depth, - }); - } - - fn into_done(self) -> (Vec, Vec) { - (self.decision_spans, self.branch_spans) - } -} - impl Builder<'_, '_> { /// If branch coverage is enabled, inject marker statements into `then_block` /// and `else_block`, and record their IDs in the table of branch spans. @@ -434,30 +195,4 @@ impl Builder<'_, '_> { branch_info.add_two_way_branch(&mut self.cfg, source_info, then_block, else_block); } - - pub(crate) fn visit_coverage_branch_operation(&mut self, logical_op: LogicalOp, span: Span) { - if let Some(branch_info) = self.coverage_branch_info.as_mut() - && let Some(mcdc_info) = branch_info.mcdc_info.as_mut() - { - mcdc_info.state.record_conditions(logical_op, span); - } - } - - pub(crate) fn mcdc_increment_depth_if_enabled(&mut self) { - if let Some(branch_info) = self.coverage_branch_info.as_mut() - && let Some(mcdc_info) = branch_info.mcdc_info.as_mut() - { - mcdc_info.state.decision_ctx_stack.push(MCDCDecisionCtx::default()); - }; - } - - pub(crate) fn mcdc_decrement_depth_if_enabled(&mut self) { - if let Some(branch_info) = self.coverage_branch_info.as_mut() - && let Some(mcdc_info) = branch_info.mcdc_info.as_mut() - { - if mcdc_info.state.decision_ctx_stack.pop().is_none() { - bug!("Unexpected empty decision stack"); - } - }; - } } diff --git a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs new file mode 100644 index 000000000000..566dba460d43 --- /dev/null +++ b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs @@ -0,0 +1,275 @@ +use std::collections::VecDeque; + +use rustc_middle::mir::coverage::{ + BlockMarkerId, ConditionId, ConditionInfo, MCDCBranchSpan, MCDCDecisionSpan, +}; +use rustc_middle::mir::{BasicBlock, SourceInfo}; +use rustc_middle::thir::LogicalOp; +use rustc_middle::ty::TyCtxt; +use rustc_span::Span; + +use crate::build::Builder; +use crate::errors::MCDCExceedsConditionNumLimit; + +/// The MCDC bitmap scales exponentially (2^n) based on the number of conditions seen, +/// So llvm sets a maximum value prevents the bitmap footprint from growing too large without the user's knowledge. +/// This limit may be relaxed if the [upstream change](https://github.com/llvm/llvm-project/pull/82448) is merged. +const MAX_CONDITIONS_NUM_IN_DECISION: usize = 6; + +#[derive(Default)] +struct MCDCDecisionCtx { + /// To construct condition evaluation tree. + decision_stack: VecDeque, + processing_decision: Option, +} + +struct MCDCState { + decision_ctx_stack: Vec, +} + +impl MCDCState { + fn new() -> Self { + Self { decision_ctx_stack: vec![MCDCDecisionCtx::default()] } + } + + /// Decision depth is given as a u16 to reduce the size of the `CoverageKind`, + /// as it is very unlikely that the depth ever reaches 2^16. + #[inline] + fn decision_depth(&self) -> u16 { + match u16::try_from(self.decision_ctx_stack.len()) + .expect( + "decision depth did not fit in u16, this is likely to be an instrumentation error", + ) + .checked_sub(1) + { + Some(d) => d, + None => bug!("Unexpected empty decision stack"), + } + } + + // At first we assign ConditionIds for each sub expression. + // If the sub expression is composite, re-assign its ConditionId to its LHS and generate a new ConditionId for its RHS. + // + // Example: "x = (A && B) || (C && D) || (D && F)" + // + // Visit Depth1: + // (A && B) || (C && D) || (D && F) + // ^-------LHS--------^ ^-RHS--^ + // ID=1 ID=2 + // + // Visit LHS-Depth2: + // (A && B) || (C && D) + // ^-LHS--^ ^-RHS--^ + // ID=1 ID=3 + // + // Visit LHS-Depth3: + // (A && B) + // LHS RHS + // ID=1 ID=4 + // + // Visit RHS-Depth3: + // (C && D) + // LHS RHS + // ID=3 ID=5 + // + // Visit RHS-Depth2: (D && F) + // LHS RHS + // ID=2 ID=6 + // + // Visit Depth1: + // (A && B) || (C && D) || (D && F) + // ID=1 ID=4 ID=3 ID=5 ID=2 ID=6 + // + // A node ID of '0' always means MC/DC isn't being tracked. + // + // If a "next" node ID is '0', it means it's the end of the test vector. + // + // As the compiler tracks expression in pre-order, we can ensure that condition info of parents are always properly assigned when their children are visited. + // - If the op is AND, the "false_next" of LHS and RHS should be the parent's "false_next". While "true_next" of the LHS is the RHS, the "true next" of RHS is the parent's "true_next". + // - If the op is OR, the "true_next" of LHS and RHS should be the parent's "true_next". While "false_next" of the LHS is the RHS, the "false next" of RHS is the parent's "false_next". + fn record_conditions(&mut self, op: LogicalOp, span: Span) { + let decision_depth = self.decision_depth(); + let Some(decision_ctx) = self.decision_ctx_stack.last_mut() else { + bug!("Unexpected empty decision_ctx_stack") + }; + let decision = match decision_ctx.processing_decision.as_mut() { + Some(decision) => { + decision.span = decision.span.to(span); + decision + } + None => decision_ctx.processing_decision.insert(MCDCDecisionSpan { + span, + conditions_num: 0, + end_markers: vec![], + decision_depth, + }), + }; + + let parent_condition = decision_ctx.decision_stack.pop_back().unwrap_or_default(); + let lhs_id = if parent_condition.condition_id == ConditionId::NONE { + decision.conditions_num += 1; + ConditionId::from(decision.conditions_num) + } else { + parent_condition.condition_id + }; + + decision.conditions_num += 1; + let rhs_condition_id = ConditionId::from(decision.conditions_num); + + let (lhs, rhs) = match op { + LogicalOp::And => { + let lhs = ConditionInfo { + condition_id: lhs_id, + true_next_id: rhs_condition_id, + false_next_id: parent_condition.false_next_id, + }; + let rhs = ConditionInfo { + condition_id: rhs_condition_id, + true_next_id: parent_condition.true_next_id, + false_next_id: parent_condition.false_next_id, + }; + (lhs, rhs) + } + LogicalOp::Or => { + let lhs = ConditionInfo { + condition_id: lhs_id, + true_next_id: parent_condition.true_next_id, + false_next_id: rhs_condition_id, + }; + let rhs = ConditionInfo { + condition_id: rhs_condition_id, + true_next_id: parent_condition.true_next_id, + false_next_id: parent_condition.false_next_id, + }; + (lhs, rhs) + } + }; + // We visit expressions tree in pre-order, so place the left-hand side on the top. + decision_ctx.decision_stack.push_back(rhs); + decision_ctx.decision_stack.push_back(lhs); + } + + fn take_condition( + &mut self, + true_marker: BlockMarkerId, + false_marker: BlockMarkerId, + ) -> (Option, Option) { + let Some(decision_ctx) = self.decision_ctx_stack.last_mut() else { + bug!("Unexpected empty decision_ctx_stack") + }; + let Some(condition_info) = decision_ctx.decision_stack.pop_back() else { + return (None, None); + }; + let Some(decision) = decision_ctx.processing_decision.as_mut() else { + bug!("Processing decision should have been created before any conditions are taken"); + }; + if condition_info.true_next_id == ConditionId::NONE { + decision.end_markers.push(true_marker); + } + if condition_info.false_next_id == ConditionId::NONE { + decision.end_markers.push(false_marker); + } + + if decision_ctx.decision_stack.is_empty() { + (Some(condition_info), decision_ctx.processing_decision.take()) + } else { + (Some(condition_info), None) + } + } +} + +pub struct MCDCInfoBuilder { + branch_spans: Vec, + decision_spans: Vec, + state: MCDCState, +} + +impl MCDCInfoBuilder { + pub fn new() -> Self { + Self { branch_spans: vec![], decision_spans: vec![], state: MCDCState::new() } + } + + pub fn visit_evaluated_condition( + &mut self, + tcx: TyCtxt<'_>, + source_info: SourceInfo, + true_block: BasicBlock, + false_block: BasicBlock, + mut inject_block_marker: impl FnMut(SourceInfo, BasicBlock) -> BlockMarkerId, + ) { + let true_marker = inject_block_marker(source_info, true_block); + let false_marker = inject_block_marker(source_info, false_block); + + let decision_depth = self.state.decision_depth(); + let (mut condition_info, decision_result) = + self.state.take_condition(true_marker, false_marker); + // take_condition() returns Some for decision_result when the decision stack + // is empty, i.e. when all the conditions of the decision were instrumented, + // and the decision is "complete". + if let Some(decision) = decision_result { + match decision.conditions_num { + 0 => { + unreachable!("Decision with no condition is not expected"); + } + 1..=MAX_CONDITIONS_NUM_IN_DECISION => { + self.decision_spans.push(decision); + } + _ => { + // Do not generate mcdc mappings and statements for decisions with too many conditions. + let rebase_idx = self.branch_spans.len() - decision.conditions_num + 1; + for branch in &mut self.branch_spans[rebase_idx..] { + branch.condition_info = None; + } + + // ConditionInfo of this branch shall also be reset. + condition_info = None; + + tcx.dcx().emit_warn(MCDCExceedsConditionNumLimit { + span: decision.span, + conditions_num: decision.conditions_num, + max_conditions_num: MAX_CONDITIONS_NUM_IN_DECISION, + }); + } + } + } + self.branch_spans.push(MCDCBranchSpan { + span: source_info.span, + condition_info, + true_marker, + false_marker, + decision_depth, + }); + } + + pub fn into_done(self) -> (Vec, Vec) { + (self.decision_spans, self.branch_spans) + } +} + +impl Builder<'_, '_> { + pub(crate) fn visit_coverage_branch_operation(&mut self, logical_op: LogicalOp, span: Span) { + if let Some(branch_info) = self.coverage_branch_info.as_mut() + && let Some(mcdc_info) = branch_info.mcdc_info.as_mut() + { + mcdc_info.state.record_conditions(logical_op, span); + } + } + + pub(crate) fn mcdc_increment_depth_if_enabled(&mut self) { + if let Some(branch_info) = self.coverage_branch_info.as_mut() + && let Some(mcdc_info) = branch_info.mcdc_info.as_mut() + { + mcdc_info.state.decision_ctx_stack.push(MCDCDecisionCtx::default()); + }; + } + + pub(crate) fn mcdc_decrement_depth_if_enabled(&mut self) { + if let Some(branch_info) = self.coverage_branch_info.as_mut() + && let Some(mcdc_info) = branch_info.mcdc_info.as_mut() + { + if mcdc_info.state.decision_ctx_stack.pop().is_none() { + bug!("Unexpected empty decision stack"); + } + }; + } +} From 6341935a13b903a563d7e8678a98f9974629e5a9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 29 Apr 2024 16:24:06 +1000 Subject: [PATCH 195/279] Remove `extern crate tracing` from numerous crates. --- compiler/rustc_ast/src/lib.rs | 3 --- compiler/rustc_ast/src/util/literal.rs | 1 + compiler/rustc_ast_lowering/src/index.rs | 1 + compiler/rustc_ast_lowering/src/item.rs | 1 + compiler/rustc_ast_lowering/src/lib.rs | 5 +---- compiler/rustc_ast_lowering/src/path.rs | 1 + compiler/rustc_builtin_macros/src/cfg_eval.rs | 1 + compiler/rustc_builtin_macros/src/lib.rs | 4 ---- compiler/rustc_builtin_macros/src/test.rs | 1 + compiler/rustc_driver_impl/src/lib.rs | 5 +---- compiler/rustc_driver_impl/src/pretty.rs | 2 +- compiler/rustc_errors/src/diagnostic.rs | 1 + compiler/rustc_errors/src/emitter.rs | 1 + compiler/rustc_errors/src/lib.rs | 4 +--- compiler/rustc_errors/src/translation.rs | 1 + compiler/rustc_expand/src/config.rs | 1 + compiler/rustc_expand/src/lib.rs | 3 --- compiler/rustc_expand/src/mbe/diagnostics.rs | 1 + compiler/rustc_expand/src/mbe/macro_rules.rs | 1 + compiler/rustc_hir/src/definitions.rs | 3 +-- compiler/rustc_hir/src/hir.rs | 3 +-- compiler/rustc_hir/src/lib.rs | 3 --- compiler/rustc_pattern_analysis/src/lib.rs | 3 --- compiler/rustc_pattern_analysis/src/lints.rs | 6 +++--- compiler/rustc_pattern_analysis/src/usefulness.rs | 11 +++++------ compiler/rustc_privacy/src/lib.rs | 4 +--- compiler/rustc_query_system/src/dep_graph/graph.rs | 1 + compiler/rustc_query_system/src/dep_graph/mod.rs | 5 ++--- .../rustc_query_system/src/dep_graph/serialized.rs | 1 + compiler/rustc_query_system/src/lib.rs | 3 --- compiler/rustc_query_system/src/query/plumbing.rs | 1 + compiler/rustc_session/src/config.rs | 1 + compiler/rustc_session/src/filesearch.rs | 7 +++---- compiler/rustc_session/src/lib.rs | 3 --- compiler/rustc_symbol_mangling/src/legacy.rs | 2 +- compiler/rustc_symbol_mangling/src/lib.rs | 4 +--- compiler/rustc_target/src/lib.rs | 3 --- compiler/rustc_target/src/spec/mod.rs | 1 + compiler/rustc_traits/src/codegen.rs | 1 + compiler/rustc_traits/src/dropck_outlives.rs | 1 + compiler/rustc_traits/src/evaluate_obligation.rs | 1 + compiler/rustc_traits/src/lib.rs | 3 --- .../rustc_traits/src/normalize_erasing_regions.rs | 1 + compiler/rustc_traits/src/normalize_projection_ty.rs | 1 + compiler/rustc_transmute/src/layout/dfa.rs | 1 + compiler/rustc_transmute/src/lib.rs | 3 --- .../rustc_transmute/src/maybe_transmutable/mod.rs | 2 ++ 47 files changed, 47 insertions(+), 70 deletions(-) diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 6b665ff72d68..9193867a10c9 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -20,9 +20,6 @@ #![feature(negative_impls)] #![feature(stmt_expr_attributes)] -#[macro_use] -extern crate tracing; - pub mod util { pub mod case; pub mod classify; diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index a17c7708e4a0..cb73b7908c2e 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -8,6 +8,7 @@ use rustc_lexer::unescape::{ use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use std::{ascii, fmt, str}; +use tracing::debug; // Escapes a string, represented as a symbol. Reuses the original symbol, // avoiding interning, if no changes are required. diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index 93be9b9b8cf5..be6c7da4108c 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -7,6 +7,7 @@ use rustc_index::IndexVec; use rustc_middle::span_bug; use rustc_middle::ty::TyCtxt; use rustc_span::{Span, DUMMY_SP}; +use tracing::{debug, instrument}; /// A visitor that walks over the HIR and collects `Node`s into a HIR map. struct NodeCollector<'a, 'hir> { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index dcce54d66c2d..0db485156ab2 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -20,6 +20,7 @@ use rustc_span::{DesugaringKind, Span, Symbol}; use rustc_target::spec::abi; use smallvec::{smallvec, SmallVec}; use thin_vec::ThinVec; +use tracing::instrument; pub(super) struct ItemLowerer<'a, 'hir> { pub(super) tcx: TyCtxt<'hir>, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 61bc7f268cf4..dd8c09ce485e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -37,11 +37,7 @@ #![feature(box_patterns)] #![feature(let_chains)] -#[macro_use] -extern crate tracing; - use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait}; - use rustc_ast::node_id::NodeMap; use rustc_ast::ptr::P; use rustc_ast::{self as ast, *}; @@ -69,6 +65,7 @@ use rustc_span::{DesugaringKind, Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; use std::collections::hash_map::Entry; use thin_vec::ThinVec; +use tracing::{debug, instrument, trace}; macro_rules! arena_vec { ($this:expr; $($x:expr),*) => ( diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index aeeb4bf9e763..7679424dceb9 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -18,6 +18,7 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{BytePos, DesugaringKind, Span, Symbol, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; +use tracing::{debug, instrument}; impl<'a, 'hir> LoweringContext<'a, 'hir> { #[instrument(level = "trace", skip(self))] diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index c192b188aa66..5f63a8ae0a8c 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -18,6 +18,7 @@ use rustc_session::Session; use rustc_span::symbol::sym; use rustc_span::Span; use smallvec::SmallVec; +use tracing::instrument; pub(crate) fn expand( ecx: &mut ExtCtxt<'_>, diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 7c7b9c2d65fb..744c7f9d0900 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -19,11 +19,7 @@ extern crate proc_macro; -#[macro_use] -extern crate tracing; - use crate::deriving::*; - use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind}; use rustc_expand::proc_macro::BangProcMacro; use rustc_span::symbol::sym; diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 134d5451b9c1..1e4bf4611cfb 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -12,6 +12,7 @@ use rustc_span::{ErrorGuaranteed, FileNameDisplayPreference, Span}; use std::assert_matches::assert_matches; use std::iter; use thin_vec::{thin_vec, ThinVec}; +use tracing::debug; /// #[test_case] is used by custom test authors to mark tests /// When building for test, it needs to make the item public and gensym the name diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index b3cba4dbfc20..12241dbe73b9 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -14,9 +14,6 @@ #![feature(panic_update_hook)] #![feature(result_flattening)] -#[macro_use] -extern crate tracing; - use rustc_ast as ast; use rustc_codegen_ssa::{traits::CodegenBackend, CodegenErrors, CodegenResults}; use rustc_const_eval::CTRL_C_RECEIVED; @@ -46,7 +43,6 @@ use rustc_span::symbol::sym; use rustc_span::FileName; use rustc_target::json::ToJson; use rustc_target::spec::{Target, TargetTriple}; - use std::cmp::max; use std::collections::BTreeMap; use std::env; @@ -62,6 +58,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, OnceLock}; use std::time::{Instant, SystemTime}; use time::OffsetDateTime; +use tracing::trace; #[allow(unused_macros)] macro do_not_use_print($($t:tt)*) { diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 40f6f7649937..fe426b8111cc 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -13,9 +13,9 @@ use rustc_session::Session; use rustc_smir::rustc_internal::pretty::write_smir_pretty; use rustc_span::symbol::Ident; use rustc_span::FileName; - use std::cell::Cell; use std::fmt::Write; +use tracing::debug; pub use self::PpMode::*; pub use self::PpSourceMode::*; diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 121c7f821c52..1610135a0efa 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -18,6 +18,7 @@ use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; use std::panic; use std::thread::panicking; +use tracing::debug; /// Error type for `DiagInner`'s `suggestions` field, indicating that /// `.disable_suggestions()` was called on the `DiagInner`. diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 6074a4a30bbd..62d08ff53823 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -35,6 +35,7 @@ use std::iter; use std::path::Path; use termcolor::{Buffer, BufferWriter, ColorChoice, ColorSpec, StandardStream}; use termcolor::{Color, WriteColor}; +use tracing::{debug, instrument, trace, warn}; /// Default column width, used in tests and when terminal dimensions cannot be determined. const DEFAULT_COLUMN_WIDTH: usize = 140; diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index fe94d41e9bee..3b884ff864ab 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -25,9 +25,6 @@ #![feature(yeet_expr)] // tidy-alphabetical-end -#[macro_use] -extern crate tracing; - extern crate self as rustc_errors; pub use codes::*; @@ -74,6 +71,7 @@ use std::num::NonZero; use std::ops::DerefMut; use std::panic; use std::path::{Path, PathBuf}; +use tracing::debug; use Level::*; diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs index bf0026568ce2..445e9b4fd6e0 100644 --- a/compiler/rustc_errors/src/translation.rs +++ b/compiler/rustc_errors/src/translation.rs @@ -6,6 +6,7 @@ pub use rustc_error_messages::FluentArgs; use std::borrow::Cow; use std::env; use std::error::Report; +use tracing::{debug, trace}; /// Convert diagnostic arguments (a rustc internal type that exists to implement /// `Encodable`/`Decodable`) into `FluentArgs` which is necessary to perform translation. diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index c95d7cdeb73a..b554a5ccd196 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -20,6 +20,7 @@ use rustc_session::Session; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use thin_vec::ThinVec; +use tracing::instrument; /// A folder that strips out items that do not belong in the current configuration. pub struct StripUnconfigured<'a> { diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 7b2202aee5b3..c095584f3c7c 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -16,9 +16,6 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(internal_features)] -#[macro_use] -extern crate tracing; - extern crate proc_macro as pm; mod placeholders; diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index 6068b271433b..5d6c3e8aa3a4 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -14,6 +14,7 @@ use rustc_span::source_map::SourceMap; use rustc_span::symbol::Ident; use rustc_span::{ErrorGuaranteed, Span}; use std::borrow::Cow; +use tracing::debug; use super::macro_rules::{parser_from_cx, NoopTracker}; diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 7099f1b0d352..df2643ad1dde 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -29,6 +29,7 @@ use rustc_span::edition::Edition; use rustc_span::hygiene::Transparency; use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent}; use rustc_span::Span; +use tracing::{debug, instrument, trace, trace_span}; use std::borrow::Cow; use std::collections::hash_map::Entry; diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index d2d18d890130..35833e258d55 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -7,15 +7,14 @@ pub use crate::def_id::DefPathHash; use crate::def_id::{CrateNum, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::def_path_hash_map::DefPathHashMap; - use rustc_data_structures::stable_hasher::{Hash64, StableHasher}; use rustc_data_structures::unord::UnordMap; use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable}; use rustc_span::symbol::{kw, sym, Symbol}; - use std::fmt::{self, Write}; use std::hash::Hash; +use tracing::{debug, instrument}; /// The `DefPathTable` maps `DefIndex`es to `DefKey`s and vice versa. /// Internally the `DefPathTable` holds a tree of `DefKey`s, where each `DefKey` diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 05431cf3780e..fc8f7466694c 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3,7 +3,6 @@ use crate::def_id::{DefId, LocalDefIdMap}; pub(crate) use crate::hir_id::{HirId, ItemLocalId, ItemLocalMap, OwnerId}; use crate::intravisit::FnKind; use crate::LangItem; - use rustc_ast as ast; use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, TraitObjectSyntax, UintTy}; @@ -21,9 +20,9 @@ use rustc_span::ErrorGuaranteed; use rustc_span::{def_id::LocalDefId, BytePos, Span, DUMMY_SP}; use rustc_target::asm::InlineAsmRegOrRegClass; use rustc_target::spec::abi::Abi; - use smallvec::SmallVec; use std::fmt; +use tracing::debug; #[derive(Debug, Copy, Clone, HashStable_Generic)] pub struct Lifetime { diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index da3c3b41d1cd..600a0dce03b9 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -10,9 +10,6 @@ #![feature(variant_count)] #![allow(internal_features)] -#[macro_use] -extern crate tracing; - extern crate self as rustc_hir; mod arena; diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index 7ec5ddbd91e1..4155540886a6 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -14,9 +14,6 @@ pub mod pat_column; pub mod rustc; pub mod usefulness; -#[macro_use] -extern crate tracing; - #[cfg(feature = "rustc")] rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_pattern_analysis/src/lints.rs b/compiler/rustc_pattern_analysis/src/lints.rs index 3ca5ebdb0dd1..1d10c9df4ab2 100644 --- a/compiler/rustc_pattern_analysis/src/lints.rs +++ b/compiler/rustc_pattern_analysis/src/lints.rs @@ -1,11 +1,11 @@ -use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; -use rustc_span::ErrorGuaranteed; - use crate::constructor::Constructor; use crate::errors::{NonExhaustiveOmittedPattern, NonExhaustiveOmittedPatternLintOnArm, Uncovered}; use crate::pat_column::PatternColumn; use crate::rustc::{RevealedTy, RustcPatCtxt, WitnessPat}; use crate::MatchArm; +use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; +use rustc_span::ErrorGuaranteed; +use tracing::instrument; /// Traverse the patterns to collect any variants of a non_exhaustive enum that fail to be mentioned /// in a given column. diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs index 7246039174af..74af9154f858 100644 --- a/compiler/rustc_pattern_analysis/src/usefulness.rs +++ b/compiler/rustc_pattern_analysis/src/usefulness.rs @@ -709,16 +709,15 @@ //! I (Nadrieril) prefer to put new tests in `ui/pattern/usefulness` unless there's a specific //! reason not to, for example if they crucially depend on a particular feature like `or_patterns`. +use self::PlaceValidity::*; +use crate::constructor::{Constructor, ConstructorSet, IntRange}; +use crate::pat::{DeconstructedPat, PatId, PatOrWild, WitnessPat}; +use crate::{Captures, MatchArm, PatCx, PrivateUninhabitedField}; use rustc_hash::FxHashSet; use rustc_index::bit_set::BitSet; use smallvec::{smallvec, SmallVec}; use std::fmt; - -use crate::constructor::{Constructor, ConstructorSet, IntRange}; -use crate::pat::{DeconstructedPat, PatId, PatOrWild, WitnessPat}; -use crate::{Captures, MatchArm, PatCx, PrivateUninhabitedField}; - -use self::PlaceValidity::*; +use tracing::{debug, instrument}; #[cfg(feature = "rustc")] use rustc_data_structures::stack::ensure_sufficient_stack; diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 2039e994aaae..a78f7e65981a 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -6,9 +6,6 @@ #![feature(try_blocks)] #![feature(let_chains)] -#[macro_use] -extern crate tracing; - mod errors; use rustc_ast::visit::{try_visit, VisitorResult}; @@ -31,6 +28,7 @@ use rustc_session::lint; use rustc_span::hygiene::Transparency; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; +use tracing::debug; use std::fmt; use std::marker::PhantomData; diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 07543b79f975..76227a78c3d6 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -15,6 +15,7 @@ use std::hash::Hash; use std::marker::PhantomData; use std::sync::atomic::Ordering; use std::sync::Arc; +use tracing::{debug, instrument}; use super::query::DepGraphQuery; use super::serialized::{GraphEncoder, SerializedDepGraph, SerializedDepNodeIndex}; diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index feb69ecd0786..cbd802958870 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -11,13 +11,12 @@ pub use graph::{hash_result, DepGraph, DepNodeIndex, TaskDepsRef, WorkProduct, W pub use query::DepGraphQuery; pub use serialized::{SerializedDepGraph, SerializedDepNodeIndex}; +use self::graph::{print_markframe_trace, MarkFrame}; use crate::ich::StableHashingContext; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_session::Session; - use std::panic; - -use self::graph::{print_markframe_trace, MarkFrame}; +use tracing::instrument; pub trait DepContext: Copy { type Deps: Deps; diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 6042aa6a2d29..b426bb888f46 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -51,6 +51,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::iter; use std::marker::PhantomData; use std::sync::Arc; +use tracing::{debug, instrument}; // The maximum value of `SerializedDepNodeIndex` leaves the upper two bits // unused so that we can store multiple index types in `CompressedHybridIndex`, diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index 6ed0b1b1d9df..fa07877ab9f3 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -5,9 +5,6 @@ #![feature(let_chains)] #![allow(rustc::potential_query_instability, internal_features)] -#[macro_use] -extern crate tracing; - pub mod cache; pub mod dep_graph; mod error; diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 3d9848395a20..d37d5bce9cc3 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -27,6 +27,7 @@ use std::fmt::Debug; use std::hash::Hash; use std::mem; use thin_vec::ThinVec; +use tracing::instrument; use super::QueryConfig; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index b0d9b7c7b00b..de1aa3aae7f8 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -33,6 +33,7 @@ use std::iter; use std::path::{Path, PathBuf}; use std::str::{self, FromStr}; use std::sync::LazyLock; +use tracing::debug; mod cfg; pub mod sigpipe; diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index aecf5954c4ca..f4e2436efb9f 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -1,13 +1,12 @@ //! A module for searching for libraries -use rustc_fs_util::try_canonicalize; +use crate::search_paths::{PathKind, SearchPath}; +use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize}; use smallvec::{smallvec, SmallVec}; use std::env; use std::fs; use std::path::{Path, PathBuf}; - -use crate::search_paths::{PathKind, SearchPath}; -use rustc_fs_util::fix_windows_verbatim_for_gcc; +use tracing::debug; #[derive(Clone)] pub struct FileSearch<'a> { diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index db52968e8a87..ce866906e1e6 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -8,9 +8,6 @@ pub mod errors; -#[macro_use] -extern crate tracing; - pub mod utils; pub use lint::{declare_lint, declare_lint_pass, declare_tool_lint, impl_lint_pass}; pub use rustc_lint_defs as lint; diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 4a4fde78d2de..0ed1f67bb821 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -5,9 +5,9 @@ use rustc_middle::bug; use rustc_middle::ty::print::{PrettyPrinter, Print, PrintError, Printer}; use rustc_middle::ty::{self, Instance, ReifyReason, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{GenericArg, GenericArgKind}; - use std::fmt::{self, Write}; use std::mem::{self, discriminant}; +use tracing::debug; pub(super) fn mangle<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index d526436f8237..745ae41085b2 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -93,9 +93,6 @@ #![feature(let_chains)] #![allow(internal_features)] -#[macro_use] -extern crate tracing; - use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; @@ -104,6 +101,7 @@ use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Instance, TyCtxt}; use rustc_session::config::SymbolManglingVersion; +use tracing::debug; mod hashed; mod legacy; diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index e096fb4fd10f..84d7930663a3 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -20,9 +20,6 @@ use std::path::{Path, PathBuf}; -#[macro_use] -extern crate tracing; - pub mod abi; pub mod asm; pub mod json; diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index c6e304a408b9..bd347c1b4b3f 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -51,6 +51,7 @@ use std::ops::{Deref, DerefMut}; use std::path::{Path, PathBuf}; use std::str::FromStr; use std::{fmt, io}; +use tracing::debug; pub mod abi; pub mod crt_objects; diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index 49e101b51e63..51f38964415b 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -13,6 +13,7 @@ use rustc_trait_selection::traits::{ ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine, TraitEngineExt, Unimplemented, }; +use tracing::debug; /// Attempts to resolve an obligation to an `ImplSource`. The result is /// a shallow `ImplSource` resolution, meaning that we do not diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index 4cee266adf96..55abd6098ec9 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -12,6 +12,7 @@ use rustc_trait_selection::traits::query::dropck_outlives::{ compute_dropck_outlives_inner, dtorck_constraint_for_ty_inner, }; use rustc_trait_selection::traits::query::{CanonicalTyGoal, NoSolution}; +use tracing::debug; pub(crate) fn provide(p: &mut Providers) { *p = Providers { dropck_outlives, adt_dtorck_constraint, ..*p }; diff --git a/compiler/rustc_traits/src/evaluate_obligation.rs b/compiler/rustc_traits/src/evaluate_obligation.rs index ce22da23fffd..c9ad096c6e9d 100644 --- a/compiler/rustc_traits/src/evaluate_obligation.rs +++ b/compiler/rustc_traits/src/evaluate_obligation.rs @@ -6,6 +6,7 @@ use rustc_trait_selection::traits::query::CanonicalPredicateGoal; use rustc_trait_selection::traits::{ EvaluationResult, Obligation, ObligationCause, OverflowError, SelectionContext, TraitQueryMode, }; +use tracing::debug; pub(crate) fn provide(p: &mut Providers) { *p = Providers { evaluate_obligation, ..*p }; diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs index 5fdbfadf1d03..bc5436f76f1c 100644 --- a/compiler/rustc_traits/src/lib.rs +++ b/compiler/rustc_traits/src/lib.rs @@ -2,9 +2,6 @@ #![recursion_limit = "256"] -#[macro_use] -extern crate tracing; - mod codegen; mod dropck_outlives; mod evaluate_obligation; diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 0576fe010278..c5ebc2d26a79 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -4,6 +4,7 @@ use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use rustc_trait_selection::traits::{Normalized, ObligationCause}; +use tracing::debug; pub(crate) fn provide(p: &mut Providers) { *p = Providers { diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 92a19fb91198..559c05eb3e78 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -10,6 +10,7 @@ use rustc_trait_selection::traits::query::{ use rustc_trait_selection::traits::{ self, FulfillmentErrorCode, ObligationCause, SelectionContext, }; +use tracing::debug; pub(crate) fn provide(p: &mut Providers) { *p = Providers { diff --git a/compiler/rustc_transmute/src/layout/dfa.rs b/compiler/rustc_transmute/src/layout/dfa.rs index 77d5a48f1584..3378d1c6754d 100644 --- a/compiler/rustc_transmute/src/layout/dfa.rs +++ b/compiler/rustc_transmute/src/layout/dfa.rs @@ -2,6 +2,7 @@ use super::{nfa, Byte, Nfa, Ref}; use crate::Map; use std::fmt; use std::sync::atomic::{AtomicU32, Ordering}; +use tracing::instrument; #[derive(PartialEq, Clone, Debug)] pub(crate) struct Dfa diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 12312271646e..8d7d81d8f735 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -2,9 +2,6 @@ #![feature(never_type)] #![allow(unused_variables)] -#[macro_use] -extern crate tracing; - pub(crate) use rustc_data_structures::fx::{FxIndexMap as Map, FxIndexSet as Set}; pub mod layout; diff --git a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs index 2789fe8f6b1d..dee5a72c3bcc 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs @@ -1,3 +1,5 @@ +use tracing::{debug, instrument, trace}; + pub(crate) mod query_context; #[cfg(test)] mod tests; From 2088de28896b7699154aecb31e0e2664a18432ba Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 29 Apr 2024 16:57:03 +1000 Subject: [PATCH 196/279] Remove `extern crate scoped_tls` from `stable_mir`. --- compiler/stable_mir/src/compiler_interface.rs | 2 +- compiler/stable_mir/src/lib.rs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs index e82d1f4813ea..231d9ba49a39 100644 --- a/compiler/stable_mir/src/compiler_interface.rs +++ b/compiler/stable_mir/src/compiler_interface.rs @@ -221,7 +221,7 @@ pub trait Context { // A thread local variable that stores a pointer to the tables mapping between TyCtxt // datastructures and stable MIR datastructures -scoped_thread_local!(static TLV: Cell<*const ()>); +scoped_tls::scoped_thread_local!(static TLV: Cell<*const ()>); pub fn run(context: &dyn Context, f: F) -> Result where diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index d1a2948ea77c..d9f988935ab1 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -16,8 +16,6 @@ //! //! The goal is to eventually be published on //! [crates.io](https://crates.io). -#[macro_use] -extern crate scoped_tls; use std::fmt; use std::fmt::Debug; From 7e4955e5027f5cc333884690070e57cbb2618378 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Sat, 24 Feb 2024 20:55:23 +0100 Subject: [PATCH 197/279] rustc: document the jobserver Explicitly document that the jobserver may be used by `rustc` and show the warning to increase the chances that this document is found when searching for solutions online. In particular, add a section about the interaction with build systems, which is intended to contain recommendations on how to integrate `rustc` with different built systems. For GNU Make, recommend using the `+` indicator. In addition, add a note about the issue with GNU Make 4.3 since it is important that users realize they should do this even if they do not expect parallelism from `rustc`. Finally, show how to workaround the issue of `$(shell ...)` calls in recursive Make (which e.g. was needed for the Linux kernel). The GNU Make 4.4 case under `--jobserver-style=pipe` is not added since it got fixed after Rust 1.76.0 already (i.e. `rustc` will not warn if it finds the negative file descriptors). For CMake, recommend using `JOB_SERVER_AWARE` and show a workaround using `$(MAKE)` for earlier versions (when using the Makefile generator). From: https://github.com/rust-lang/rust/issues/120515 Cc: @petrochenkov @belovdv @weihanglo @bjorn3 Signed-off-by: Miguel Ojeda --- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/jobserver.md | 86 ++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 src/doc/rustc/src/jobserver.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 1f9307203bc3..345cf6146913 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -3,6 +3,7 @@ - [What is rustc?](what-is-rustc.md) - [Command-line Arguments](command-line-arguments.md) - [Codegen Options](codegen-options/index.md) +- [Jobserver](jobserver.md) - [Lints](lints/index.md) - [Lint Levels](lints/levels.md) - [Lint Groups](lints/groups.md) diff --git a/src/doc/rustc/src/jobserver.md b/src/doc/rustc/src/jobserver.md new file mode 100644 index 000000000000..da82b0df7c62 --- /dev/null +++ b/src/doc/rustc/src/jobserver.md @@ -0,0 +1,86 @@ +# Jobserver + +Internally, `rustc` may take advantage of parallelism. `rustc` will coordinate +with the build system calling it if a [GNU Make jobserver] is passed in the +`MAKEFLAGS` environment variable. Other flags may have an effect as well, such +as [`CARGO_MAKEFLAGS`]. If a jobserver is not passed, then `rustc` will choose +the number of jobs to use. + +Starting with Rust 1.76.0, `rustc` will warn if a jobserver appears to be +available but is not accessible, e.g.: + +```console +$ echo 'fn main() {}' | MAKEFLAGS=--jobserver-auth=3,4 rustc - +warning: failed to connect to jobserver from environment variable `MAKEFLAGS="--jobserver-auth=3,4"`: cannot open file descriptor 3 from the jobserver environment variable value: Bad file descriptor (os error 9) + | + = note: the build environment is likely misconfigured +``` + +## Integration with build systems + +The following subsections contain recommendations on how to integrate `rustc` +with build systems so that the jobserver is handled appropriately. + +### GNU Make + +When calling `rustc` from GNU Make, it is recommended that all `rustc` +invocations are marked as recursive in the `Makefile` (by prefixing the command +line with the `+` indicator), so that GNU Make enables the jobserver for them. +For instance: + + + +```make +x: + +@echo 'fn main() {}' | rustc - +``` + +In particular, GNU Make 4.3 (a widely used version as of 2024) passes a simple +pipe jobserver in `MAKEFLAGS` even when it was not made available for the child +process, which in turn means `rustc` will warn about it. For instance, if the +`+` indicator is removed from the example above and GNU Make is called with e.g. +`make -j2`, then the aforementioned warning will trigger. + +For calls to `rustc` inside `$(shell ...)` inside a recursive Make, one can +disable the jobserver manually by clearing the `MAKEFLAGS` variable, e.g.: + +```make +S := $(shell MAKEFLAGS= rustc --print sysroot) + +x: + @$(MAKE) y + +y: + @echo $(S) +``` + +### CMake + +CMake 3.28 supports the `JOB_SERVER_AWARE` option in its [`add_custom_target`] +command, e.g.: + +```cmake +cmake_minimum_required(VERSION 3.28) +project(x) +add_custom_target(x + JOB_SERVER_AWARE TRUE + COMMAND echo 'fn main() {}' | rustc - +) +``` + +For earlier versions, when using CMake with the Makefile generator, one +workaround is to have [`$(MAKE)`] somewhere in the command so that GNU Make +treats it as a recursive Make call, e.g.: + +```cmake +cmake_minimum_required(VERSION 3.22) +project(x) +add_custom_target(x + COMMAND DUMMY_VARIABLE=$(MAKE) echo 'fn main() {}' | rustc - +) +``` + +[GNU Make jobserver]: https://www.gnu.org/software/make/manual/html_node/POSIX-Jobserver.html +[`CARGO_MAKEFLAGS`]: https://doc.rust-lang.org/cargo/reference/environment-variables.html +[`add_custom_target`]: https://cmake.org/cmake/help/latest/command/add_custom_target.html +[`$(MAKE)`]: https://www.gnu.org/software/make/manual/html_node/MAKE-Variable.html From de0c02c9abaeae6e07241a7ea1d9e4fe049c2fc4 Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Mon, 29 Apr 2024 17:52:16 +0100 Subject: [PATCH 198/279] Recapitalise ARMvX{-Y} to ArmvX{-Y} Yes it looks weird, but this is how Arm write it now. I left ARM64 alone, because it's a Microsoft/Apple term but not an Arm term (they have Armv8-A and Armv9-A architectures, which say that A64 instructions are executed when in the Aarch64 state), and I don't want to get into that, especially for a Tier 1 target. --- src/doc/rustc/src/platform-support.md | 98 +++++++++---------- .../src/platform-support/arm-none-eabi.md | 2 +- .../armeb-unknown-linux-gnueabi.md | 10 +- .../src/platform-support/armv4t-none-eabi.md | 6 +- .../src/platform-support/armv5te-none-eabi.md | 6 +- .../platform-support/armv6k-nintendo-3ds.md | 2 +- .../armv7-unknown-linux-uclibceabi.md | 6 +- .../armv7-unknown-linux-uclibceabihf.md | 2 +- .../src/platform-support/armv7r-none-eabi.md | 2 +- .../platform-support/armv8r-none-eabihf.md | 2 +- .../platform-support/thumbv6m-none-eabi.md | 6 +- .../platform-support/thumbv7em-none-eabi.md | 4 +- .../platform-support/thumbv7m-none-eabi.md | 6 +- .../thumbv8m.base-none-eabi.md | 6 +- .../thumbv8m.main-none-eabi.md | 4 +- 15 files changed, 81 insertions(+), 81 deletions(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index cdab3d4401ef..764798a80e6d 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -89,9 +89,9 @@ target | notes `aarch64-apple-darwin` | ARM64 macOS (11.0+, Big Sur+) `aarch64-pc-windows-msvc` | ARM64 Windows MSVC `aarch64-unknown-linux-musl` | ARM64 Linux with musl 1.2.3 -`arm-unknown-linux-gnueabi` | ARMv6 Linux (kernel 3.2, glibc 2.17) -`arm-unknown-linux-gnueabihf` | ARMv6 Linux, hardfloat (kernel 3.2, glibc 2.17) -`armv7-unknown-linux-gnueabihf` | ARMv7-A Linux, hardfloat (kernel 3.2, glibc 2.17) +`arm-unknown-linux-gnueabi` | Armv6 Linux (kernel 3.2, glibc 2.17) +`arm-unknown-linux-gnueabihf` | Armv6 Linux, hardfloat (kernel 3.2, glibc 2.17) +`armv7-unknown-linux-gnueabihf` | Armv7-A Linux, hardfloat (kernel 3.2, glibc 2.17) [`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36) `powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2, glibc 2.17) `powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2, glibc 2.17) @@ -143,21 +143,21 @@ target | std | notes `aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat `aarch64-unknown-none` | * | Bare ARM64, hardfloat [`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | ARM64 UEFI -[`arm-linux-androideabi`](platform-support/android.md) | ✓ | ARMv6 Android -`arm-unknown-linux-musleabi` | ✓ | ARMv6 Linux with musl 1.2.3 -`arm-unknown-linux-musleabihf` | ✓ | ARMv6 Linux with musl 1.2.3, hardfloat -[`armebv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare ARMv7-R, Big Endian -[`armebv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare ARMv7-R, Big Endian, hardfloat -`armv5te-unknown-linux-gnueabi` | ✓ | ARMv5TE Linux (kernel 4.4, glibc 2.23) -`armv5te-unknown-linux-musleabi` | ✓ | ARMv5TE Linux with musl 1.2.3 -[`armv7-linux-androideabi`](platform-support/android.md) | ✓ | ARMv7-A Android -`armv7-unknown-linux-gnueabi` | ✓ | ARMv7-A Linux (kernel 4.15, glibc 2.27) -`armv7-unknown-linux-musleabi` | ✓ | ARMv7-A Linux with musl 1.2.3 -`armv7-unknown-linux-musleabihf` | ✓ | ARMv7-A Linux with musl 1.2.3, hardfloat -[`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | ARMv7-A OpenHarmony -[`armv7a-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare ARMv7-A -[`armv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare ARMv7-R -[`armv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare ARMv7-R, hardfloat +[`arm-linux-androideabi`](platform-support/android.md) | ✓ | Armv6 Android +`arm-unknown-linux-musleabi` | ✓ | Armv6 Linux with musl 1.2.3 +`arm-unknown-linux-musleabihf` | ✓ | Armv6 Linux with musl 1.2.3, hardfloat +[`armebv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian +[`armebv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian, hardfloat +`armv5te-unknown-linux-gnueabi` | ✓ | Armv5TE Linux (kernel 4.4, glibc 2.23) +`armv5te-unknown-linux-musleabi` | ✓ | Armv5TE Linux with musl 1.2.3 +[`armv7-linux-androideabi`](platform-support/android.md) | ✓ | Armv7-A Android +`armv7-unknown-linux-gnueabi` | ✓ | Armv7-A Linux (kernel 4.15, glibc 2.27) +`armv7-unknown-linux-musleabi` | ✓ | Armv7-A Linux with musl 1.2.3 +`armv7-unknown-linux-musleabihf` | ✓ | Armv7-A Linux with musl 1.2.3, hardfloat +[`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | Armv7-A OpenHarmony +[`armv7a-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare Armv7-A +[`armv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R +[`armv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, hardfloat `i586-pc-windows-msvc` | * | 32-bit Windows w/o SSE [^x86_32-floats-x87] `i586-unknown-linux-gnu` | ✓ | 32-bit Linux w/o SSE (kernel 3.2, glibc 2.17) [^x86_32-floats-x87] `i586-unknown-linux-musl` | ✓ | 32-bit Linux w/o SSE, musl 1.2.3 [^x86_32-floats-x87] @@ -178,15 +178,15 @@ target | std | notes `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA) `sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4, glibc 2.23) `sparcv9-sun-solaris` | ✓ | SPARC Solaris 11, illumos -[`thumbv6m-none-eabi`](platform-support/thumbv6m-none-eabi.md) | * | Bare ARMv6-M -[`thumbv7em-none-eabi`](platform-support/thumbv7em-none-eabi.md) | * | Bare ARMv7E-M -[`thumbv7em-none-eabihf`](platform-support/thumbv7em-none-eabi.md) | * | Bare ARMV7E-M, hardfloat -[`thumbv7m-none-eabi`](platform-support/thumbv7m-none-eabi.md) | * | Bare ARMv7-M -[`thumbv7neon-linux-androideabi`](platform-support/android.md) | ✓ | Thumb2-mode ARMv7-A Android with NEON -`thumbv7neon-unknown-linux-gnueabihf` | ✓ | Thumb2-mode ARMv7-A Linux with NEON (kernel 4.4, glibc 2.23) -[`thumbv8m.base-none-eabi`](platform-support/thumbv8m.base-none-eabi.md) | * | Bare ARMv8-M Baseline -[`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare ARMv8-M Mainline -[`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare ARMv8-M Mainline, hardfloat +[`thumbv6m-none-eabi`](platform-support/thumbv6m-none-eabi.md) | * | Bare Armv6-M +[`thumbv7em-none-eabi`](platform-support/thumbv7em-none-eabi.md) | * | Bare Armv7E-M +[`thumbv7em-none-eabihf`](platform-support/thumbv7em-none-eabi.md) | * | Bare Armv7E-M, hardfloat +[`thumbv7m-none-eabi`](platform-support/thumbv7m-none-eabi.md) | * | Bare Armv7-M +[`thumbv7neon-linux-androideabi`](platform-support/android.md) | ✓ | Thumb2-mode Armv7-A Android with NEON +`thumbv7neon-unknown-linux-gnueabihf` | ✓ | Thumb2-mode Armv7-A Linux with NEON (kernel 4.4, glibc 2.23) +[`thumbv8m.base-none-eabi`](platform-support/thumbv8m.base-none-eabi.md) | * | Bare Armv8-M Baseline +[`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline +[`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline, hardfloat `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten `wasm32-unknown-unknown` | ✓ | WebAssembly `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename]) @@ -264,27 +264,27 @@ target | std | host | notes `aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI) `aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian) [`aarch64_be-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD (big-endian) -[`arm64_32-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARM Apple WatchOS 64-bit with 32-bit pointers -[`armeb-unknown-linux-gnueabi`](platform-support/armeb-unknown-linux-gnueabi.md) | ✓ | ? | ARM BE8 the default ARM big-endian architecture since [ARMv6](https://developer.arm.com/documentation/101754/0616/armlink-Reference/armlink-Command-line-Options/--be8?lang=en). -[`armv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Bare ARMv4T -`armv4t-unknown-linux-gnueabi` | ? | | ARMv4T Linux -[`armv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * | | Bare ARMv5TE -`armv5te-unknown-linux-uclibceabi` | ? | | ARMv5TE Linux with uClibc -`armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD -[`armv6-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | ARMv6 NetBSD w/hard-float -[`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain) -[`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ✓ | | ARMv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain) -[`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | ARMv7-A Linux with uClibc, softfloat -[`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | ARMv7-A Linux with uClibc, hardfloat -`armv7-unknown-freebsd` | ✓ | ✓ | ARMv7-A FreeBSD -[`armv7-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | ARMv7-A NetBSD w/hard-float -`armv7-wrs-vxworks-eabihf` | ? | | ARMv7-A for VxWorks +[`arm64_32-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | Arm Apple WatchOS 64-bit with 32-bit pointers +[`armeb-unknown-linux-gnueabi`](platform-support/armeb-unknown-linux-gnueabi.md) | ✓ | ? | Arm BE8 the default Arm big-endian architecture since [Armv6](https://developer.arm.com/documentation/101754/0616/armlink-Reference/armlink-Command-line-Options/--be8?lang=en). +[`armv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Bare Armv4T +`armv4t-unknown-linux-gnueabi` | ? | | Armv4T Linux +[`armv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * | | Bare Armv5TE +`armv5te-unknown-linux-uclibceabi` | ? | | Armv5TE Linux with uClibc +`armv6-unknown-freebsd` | ✓ | ✓ | Armv6 FreeBSD +[`armv6-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv6 NetBSD w/hard-float +[`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | Armv6k Nintendo 3DS, Horizon (Requires devkitARM toolchain) +[`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ✓ | | Armv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain) +[`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | Armv7-A Linux with uClibc, softfloat +[`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | Armv7-A Linux with uClibc, hardfloat +`armv7-unknown-freebsd` | ✓ | ✓ | Armv7-A FreeBSD +[`armv7-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv7-A NetBSD w/hard-float +`armv7-wrs-vxworks-eabihf` | ? | | Armv7-A for VxWorks [`armv7a-kmc-solid_asp3-eabi`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3 [`armv7a-kmc-solid_asp3-eabihf`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3, hardfloat -[`armv7a-none-eabihf`](platform-support/arm-none-eabi.md) | * | | Bare ARMv7-A, hardfloat -[`armv7k-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARMv7-A Apple WatchOS -`armv7s-apple-ios` | ✓ | | ARMv7-A Apple-A6 Apple iOS -[`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * | | Bare ARMv8-R, hardfloat +[`armv7a-none-eabihf`](platform-support/arm-none-eabi.md) | * | | Bare Armv7-A, hardfloat +[`armv7k-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | Armv7-A Apple WatchOS +`armv7s-apple-ios` | ✓ | | Armv7-A Apple-A6 Apple iOS +[`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * | | Bare Armv8-R, hardfloat `avr-unknown-gnu-atmega328` | * | | AVR. Requires `-Z build-std=core` `bpfeb-unknown-none` | * | | BPF (big endian) `bpfel-unknown-none` | * | | BPF (little endian) @@ -360,11 +360,11 @@ target | std | host | notes [`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * | | Bare 32-bit SPARC V7+ [`sparc64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/sparc64 [`sparc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/sparc64 -[`thumbv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Thumb-mode Bare ARMv4T -[`thumbv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * | | Thumb-mode Bare ARMv5TE +[`thumbv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Thumb-mode Bare Armv4T +[`thumbv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * | | Thumb-mode Bare Armv5TE `thumbv7a-pc-windows-msvc` | ? | | `thumbv7a-uwp-windows-msvc` | ✓ | | -`thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode ARMv7-A Linux with NEON, musl 1.2.3 +`thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode Armv7-A Linux with NEON, musl 1.2.3 [`wasm32-wasip2`](platform-support/wasm32-wasip2.md) | ✓ | | WebAssembly [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly `x86_64-apple-ios-macabi` | ✓ | | Apple Catalyst on x86_64 diff --git a/src/doc/rustc/src/platform-support/arm-none-eabi.md b/src/doc/rustc/src/platform-support/arm-none-eabi.md index e7ffc23d2800..4560860b88ba 100644 --- a/src/doc/rustc/src/platform-support/arm-none-eabi.md +++ b/src/doc/rustc/src/platform-support/arm-none-eabi.md @@ -31,7 +31,7 @@ ## Common Target Details This documentation covers details that apply to a range of bare-metal targets -for 32-bit ARM CPUs. In addition, target specific details may be covered in +for 32-bit Arm CPUs. In addition, target specific details may be covered in their own document. If a target ends in `eabi`, that target uses the so-called *soft-float ABI*: diff --git a/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md b/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md index 32d3440f1dc9..e7e3fd01c4dc 100644 --- a/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md +++ b/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md @@ -1,22 +1,22 @@ # armeb-unknown-linux-gnueabi **Tier: 3** -Target for cross-compiling Linux user-mode applications targeting the ARM BE8 architecture. +Target for cross-compiling Linux user-mode applications targeting the Arm BE8 architecture. ## Overview -BE8 architecture retains the same little-endian ordered code-stream used by conventional little endian ARM systems, however the data accesses are in big-endian. BE8 is used primarily in high-performance networking applications where the ability to read packets in their native "Network Byte Order" is important (many network protocols transmit data in big-endian byte order for their wire formats). +BE8 architecture retains the same little-endian ordered code-stream used by conventional little endian Arm systems, however the data accesses are in big-endian. BE8 is used primarily in high-performance networking applications where the ability to read packets in their native "Network Byte Order" is important (many network protocols transmit data in big-endian byte order for their wire formats). ## History -BE8 architecture is the default big-endian architecture for ARM since [ARMv6](https://developer.arm.com/documentation/101754/0616/armlink-Reference/armlink-Command-line-Options/--be8?lang=en). It's predecessor, used for ARMv4 and ARMv5 devices was [BE32](https://developer.arm.com/documentation/dui0474/j/linker-command-line-options/--be32). On ARMv6 architecture, endianness can be configured via [system registers](https://developer.arm.com/documentation/ddi0290/g/unaligned-and-mixed-endian-data-access-support/mixed-endian-access-support/interaction-between-the-bus-protocol-and-the-core-endianness). However, BE32 was withdrawn for [ARMv7](https://developer.arm.com/documentation/ddi0406/cb/Appendixes/Deprecated-and-Obsolete-Features/Obsolete-features/Support-for-BE-32-endianness-model) onwards. +BE8 architecture is the default big-endian architecture for Arm since [Armv6](https://developer.arm.com/documentation/101754/0616/armlink-Reference/armlink-Command-line-Options/--be8?lang=en). It's predecessor, used for Armv4 and Armv5 devices was [BE32](https://developer.arm.com/documentation/dui0474/j/linker-command-line-options/--be32). On Armv6 architecture, endianness can be configured via [system registers](https://developer.arm.com/documentation/ddi0290/g/unaligned-and-mixed-endian-data-access-support/mixed-endian-access-support/interaction-between-the-bus-protocol-and-the-core-endianness). However, BE32 was withdrawn for [Armv7](https://developer.arm.com/documentation/ddi0406/cb/Appendixes/Deprecated-and-Obsolete-Features/Obsolete-features/Support-for-BE-32-endianness-model) onwards. ## Target Maintainers * [@WorksButNotTested](https://github.com/WorksButNotTested) ## Requirements -The target is cross-compiled. This target supports `std` in the normal way (indeed only nominal changes are required from the standard ARM configuration). +The target is cross-compiled. This target supports `std` in the normal way (indeed only nominal changes are required from the standard Arm configuration). ## Target definition -The target definition can be seen [here](https://github.com/rust-lang/rust/tree/master/compiler/rustc_target/src/spec/armeb_unknown_linux_gnueabi.rs). In particular, it should be noted that the `features` specify that this target is built for the ARMv8 core. Though this can likely be modified as required. +The target definition can be seen [here](https://github.com/rust-lang/rust/tree/master/compiler/rustc_target/src/spec/armeb_unknown_linux_gnueabi.rs). In particular, it should be noted that the `features` specify that this target is built for the Armv8 core. Though this can likely be modified as required. ## Building the target Because it is Tier 3, rust does not yet ship pre-compiled artifacts for this target. diff --git a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md index 29c47db8351c..f4c8dd46f1d0 100644 --- a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md @@ -2,12 +2,12 @@ Tier 3 -Bare-metal target for any cpu in the ARMv4T architecture family, supporting -ARM/Thumb code interworking (aka `a32`/`t32`), with ARM code as the default code +Bare-metal target for any cpu in the Armv4T architecture family, supporting +ARM/Thumb code interworking (aka `A32`/`T32`), with ARM code as the default code generation. In particular this supports the Game Boy Advance (GBA), but there's nothing -GBA-specific with this target, so any ARMv4T device should work fine. +GBA-specific with this target, so any Armv4T device should work fine. See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all `arm-none-eabi` targets. diff --git a/src/doc/rustc/src/platform-support/armv5te-none-eabi.md b/src/doc/rustc/src/platform-support/armv5te-none-eabi.md index 37284ba72099..41621e070bb4 100644 --- a/src/doc/rustc/src/platform-support/armv5te-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv5te-none-eabi.md @@ -2,11 +2,11 @@ **Tier: 3** -Bare-metal target for any cpu in the ARMv5TE architecture family, supporting -ARM/Thumb code interworking (aka `a32`/`t32`), with `a32` code as the default code +Bare-metal target for any cpu in the Armv5TE architecture family, supporting +ARM/Thumb code interworking (aka `A32`/`T32`), with `A32` code as the default code generation. -The `thumbv5te-none-eabi` target is the same as this one, but the instruction set defaults to `t32`. +The `thumbv5te-none-eabi` target is the same as this one, but the instruction set defaults to `T32`. See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all `arm-none-eabi` targets. diff --git a/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md b/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md index 540e5a4af938..160986aeae94 100644 --- a/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md +++ b/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md @@ -2,7 +2,7 @@ **Tier: 3** -The Nintendo 3DS platform, which has an ARMv6K processor, and its associated +The Nintendo 3DS platform, which has an Armv6k processor, and its associated operating system (`horizon`). Rust support for this target is not affiliated with Nintendo, and is not derived diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md index e351ea001300..f22a20835c1a 100644 --- a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md +++ b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md @@ -2,7 +2,7 @@ **Tier: 3** -This target supports ARMv7 softfloat CPUs and uses the uclibc-ng standard library. This is a common configuration on many consumer routers (e.g., Netgear R7000, Asus RT-AC68U). +This target supports Armv7-A softfloat CPUs and uses the uclibc-ng standard library. This is a common configuration on many consumer routers (e.g., Netgear R7000, Asus RT-AC68U). ## Target maintainers @@ -16,7 +16,7 @@ This target supports host tools and std. ## Building the target -You will need to download or build a `'C'` cross toolchain that targets ARMv7 softfloat and that uses the uclibc-ng standard library. If your target hardware is something like a router or an embedded device, keep in mind that manufacturer supplied SDKs for this class of CPU could be outdated and potentially unsuitable for bootstrapping rust. +You will need to download or build a `'C'` cross toolchain that targets Armv7-A softfloat and that uses the uclibc-ng standard library. If your target hardware is something like a router or an embedded device, keep in mind that manufacturer supplied SDKs for this class of CPU could be outdated and potentially unsuitable for bootstrapping rust. [Here](https://github.com/lancethepants/tomatoware-toolchain) is a sample toolchain that is built using [buildroot](https://buildroot.org/). It uses modern toolchain components, older thus universal kernel headers (2.6.36.4), and is used for a project called [Tomatoware](https://github.com/lancethepants/tomatoware). This toolchain is patched so that its sysroot is located at /mmc (e.g., /mmc/bin, /mmc/lib, /mmc/include). This is useful in scenarios where the root filesystem is read-only but you are able attach external storage loaded with user applications. Tomatoware is an example of this that even allows you to run various compilers and developer tools natively on the target device. @@ -46,7 +46,7 @@ The following assumes you are using the Tomatoware toolchain and environment. Ad ### Native compilation -Since this target supports host tools, you can natively build rust applications directly on your target device. This can be convenient because it removes the complexities of cross compiling and you can immediately test and deploy your binaries. One downside is that compiling on your ARMv7 CPU will probably be much slower than cross compilation on your x86 machine. +Since this target supports host tools, you can natively build rust applications directly on your target device. This can be convenient because it removes the complexities of cross compiling and you can immediately test and deploy your binaries. One downside is that compiling on your Armv7-A CPU will probably be much slower than cross compilation on your x86 machine. To setup native compilation: diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md index 1f029406367a..1c8acc09c774 100644 --- a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md +++ b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md @@ -2,7 +2,7 @@ **Tier: 3** -This tier supports the ARMv7 processor running a Linux kernel and uClibc-ng standard library. It provides full support for rust and the rust standard library. +This tier supports the Armv7-A processor running a Linux kernel and uClibc-ng standard library. It provides full support for rust and the rust standard library. ## Designated Developers diff --git a/src/doc/rustc/src/platform-support/armv7r-none-eabi.md b/src/doc/rustc/src/platform-support/armv7r-none-eabi.md index 670cead9e006..5f0dc6a7115b 100644 --- a/src/doc/rustc/src/platform-support/armv7r-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv7r-none-eabi.md @@ -2,7 +2,7 @@ **Tier: 2** -Bare-metal target for CPUs in the ARMv7-R architecture family, supporting +Bare-metal target for CPUs in the Armv7-R architecture family, supporting dual ARM/Thumb mode, with ARM mode as the default. Processors in this family include the [Arm Cortex-R4, 5, 7, and 8][cortex-r]. diff --git a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md index 588e5d7c9944..6f80a06020ff 100644 --- a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md +++ b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md @@ -2,7 +2,7 @@ **Tier: 3** -Bare-metal target for CPUs in the ARMv8-R architecture family, supporting +Bare-metal target for CPUs in the Armv8-R architecture family, supporting dual ARM/Thumb mode, with ARM mode as the default. Processors in this family include the Arm [Cortex-R52][cortex-r52] diff --git a/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md index 32f2a573973f..f4ed6201bbdc 100644 --- a/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md @@ -2,7 +2,7 @@ **Tier: 2** -Bare-metal target for CPUs in the [ARMv6-M] architecture family, supporting a +Bare-metal target for CPUs in the [Armv6-M] architecture family, supporting a subset of the [T32 ISA][t32-isa]. Processors in this family include the: @@ -16,10 +16,10 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all This target uses the soft-float ABI: functions which take `f32` or `f64` as arguments will have those values packed into integer registers. This is the -only option because there is no FPU support in [ARMv6-M]. +only option because there is no FPU support in [Armv6-M]. [t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture -[ARMv6-M]: https://developer.arm.com/documentation/ddi0419/latest/ +[Armv6-M]: https://developer.arm.com/documentation/ddi0419/latest/ [cortex-m0]: https://developer.arm.com/Processors/Cortex-M0 [cortex-m0plus]: https://developer.arm.com/Processors/Cortex-M0+ [cortex-m1]: https://developer.arm.com/Processors/Cortex-M1 diff --git a/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md index 698c8ae7a655..f25ef0383b18 100644 --- a/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md @@ -2,7 +2,7 @@ **Tier: 2** -Bare-metal target for CPUs in the [ARMv7E-M] architecture family, supporting a +Bare-metal target for CPUs in the [Armv7E-M] architecture family, supporting a subset of the [T32 ISA][t32-isa]. Processors in this family include the: @@ -15,7 +15,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all `eabihf` ABI. [t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture -[ARMv7E-M]: https://developer.arm.com/documentation/ddi0403/latest/ +[Armv7E-M]: https://developer.arm.com/documentation/ddi0403/latest/ [cortex-m4]: https://developer.arm.com/Processors/Cortex-M4 [cortex-m7]: https://developer.arm.com/Processors/Cortex-M7 diff --git a/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md index 793e0d7d2de9..b258033bb0fa 100644 --- a/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md @@ -2,7 +2,7 @@ **Tier: 2** -Bare-metal target for CPUs in the [ARMv7-M] architecture family, supporting a +Bare-metal target for CPUs in the [Armv7-M] architecture family, supporting a subset of the [T32 ISA][t32-isa]. Processors in this family include the: @@ -14,10 +14,10 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all This target uses the soft-float ABI: functions which take `f32` or `f64` as arguments will have those values packed into integer registers. This is the -only option because there is no FPU support in [ARMv7-M]. +only option because there is no FPU support in [Armv7-M]. [t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture -[ARMv7-M]: https://developer.arm.com/documentation/ddi0403/latest/ +[Armv7-M]: https://developer.arm.com/documentation/ddi0403/latest/ [cortex-m3]: https://developer.arm.com/Processors/Cortex-M3 ## Target maintainers diff --git a/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md index c63620067acf..0ae4e3e94bd8 100644 --- a/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md @@ -2,7 +2,7 @@ **Tier: 2** -Bare-metal target for CPUs in the Baseline [ARMv8-M] architecture family, +Bare-metal target for CPUs in the Baseline [Armv8-M] architecture family, supporting a subset of the [T32 ISA][t32-isa]. Processors in this family include the: @@ -14,10 +14,10 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all This target uses the soft-float ABI: functions which take `f32` or `f64` as arguments will have those values packed into integer registers. This is the -only option because there is no FPU support in [ARMv8-M] Baseline. +only option because there is no FPU support in [Armv8-M] Baseline. [t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture -[ARMv8-M]: https://developer.arm.com/documentation/ddi0553/latest/ +[Armv8-M]: https://developer.arm.com/documentation/ddi0553/latest/ [cortex-m23]: https://developer.arm.com/Processors/Cortex-M23 ## Target maintainers diff --git a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md index 9541e1d582c2..4e696f9c3046 100644 --- a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md +++ b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md @@ -2,7 +2,7 @@ **Tier: 2** -Bare-metal target for CPUs in the Mainline [ARMv8-M] architecture family, +Bare-metal target for CPUs in the Mainline [Armv8-M] architecture family, supporting a subset of the [T32 ISA][t32-isa]. Processors in this family include the: @@ -17,7 +17,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all `eabihf` ABI. [t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture -[ARMv8-M]: https://developer.arm.com/documentation/ddi0553/latest/ +[Armv8-M]: https://developer.arm.com/documentation/ddi0553/latest/ [cortex-m33]: https://developer.arm.com/Processors/Cortex-M33 [cortex-m35p]: https://developer.arm.com/Processors/Cortex-M35P [cortex-m55]: https://developer.arm.com/Processors/Cortex-M55 From fcaba9ce5c94b07c2394e61d65711c14bb33d6cb Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Tue, 30 Apr 2024 10:00:19 +0100 Subject: [PATCH 199/279] arm target docs: clarify A32/T32/Arm ISA/Thumb ISA/Thumb-2 ISA --- .../src/platform-support/arm-none-eabi.md | 51 +++++++++++++------ 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/src/doc/rustc/src/platform-support/arm-none-eabi.md b/src/doc/rustc/src/platform-support/arm-none-eabi.md index 4560860b88ba..0b1b10e4762e 100644 --- a/src/doc/rustc/src/platform-support/arm-none-eabi.md +++ b/src/doc/rustc/src/platform-support/arm-none-eabi.md @@ -34,21 +34,43 @@ This documentation covers details that apply to a range of bare-metal targets for 32-bit Arm CPUs. In addition, target specific details may be covered in their own document. -If a target ends in `eabi`, that target uses the so-called *soft-float ABI*: -functions which take `f32` or `f64` as arguments will have those values packed -into integer registers. This means that an FPU is not required from an ABI +There are two 32-bit instruction set architectures (ISAs) defined by Arm: + +- The [*A32 ISA*][a32-isa], with fixed-width 32-bit instructions. Previously + known as the *Arm* ISA, this originated with the original ARM1 of 1985 and has + been updated by various revisions to the architecture specifications ever + since. +- The [*T32 ISA*][t32-isa], with a mix of 16-bit and 32-bit width instructions. + Note that this term includes both the original 16-bit width *Thumb* ISA + introduced with the Armv4T architecture in 1994, and the later 16/32-bit sized + *Thumb-2* ISA introduced with the Armv6T2 architecture in 2003. Again, these + ISAs have been revised by subsequent revisions to the relevant Arm + architecture specifications. + +There is also a 64-bit ISA with fixed-width 32-bit instructions called the *A64 +ISA*, but targets which implement that instruction set generally start with +`aarch64*` and are discussed elsewhere. + +Rust targets starting with `arm*` generate Arm (A32) code by default, whilst +targets named `thumb*` generate Thumb (T32) code by default. Most Arm chips +support both Thumb mode and Arm mode, with the notable exception that M-profile +processors (`thumbv*m*-none-eabi*` targets) *only* support Thumb-mode. + +Rust targets ending with `eabi` use the so-called *soft-float ABI*: functions +which take `f32` or `f64` as arguments will have those values packed into +integer registers. This means that an FPU is not required from an ABI perspective, but within a function floating-point instructions may still be used if the code is compiled with a `target-cpu` or `target-feature` option that enables FPU support. -If a target ends in `eabihf`, that target uses the so-called *hard-float ABI*: -functions which take `f32` or `f64` as arguments will have them passed via FPU -registers. These targets therefore require the availability of an FPU and will -assume some baseline level of floating-point support is available (which can -vary depending on the target). More advanced floating-point instructions may be -generated if the code is compiled with a `target-cpu` or `target-feature` option -that enables such additional FPU support. For example, if a given hard-float -target has baseline *single-precision* (`f32`) support in hardware, there may be +Rust targets ending in `eabihf` use the so-called *hard-float ABI*: functions +which take `f32` or `f64` as arguments will have them passed via FPU registers. +These targets therefore require the availability of an FPU and will assume some +baseline level of floating-point support is available (which can vary depending +on the target). More advanced floating-point instructions may be generated if +the code is compiled with a `target-cpu` or `target-feature` option that enables +such additional FPU support. For example, if a given hard-float target has +baseline *single-precision* (`f32`) support in hardware, there may be `target-cpu` or `target-feature` options that tell LLVM to assume your processor in fact also has *double-precision* (`f64`) support. @@ -59,6 +81,9 @@ processor cannot support will be lowered to library calls (like `__aeabi_dadd`) which perform the floating-point operation in software using integer instructions. +[t32-isa]: https://developer.arm.com/Architectures/T32%20Instruction%20Set%20Architecture +[a32-isa]: https://developer.arm.com/Architectures/A32%20Instruction%20Set%20Architecture + ## Target CPU and Target Feature options It is possible to tell Rust (or LLVM) that you have a specific model of Arm @@ -126,10 +151,6 @@ according to the specific device you are using. Pass `-Clink-arg=-Tyour_script.ld` as a rustc argument to make the linker use `your_script.ld` during linking. -Targets named `thumb*` instead of `arm*` generate Thumb (T32) code by default -instead of Arm (A32) code. Most Arm chips support both Thumb mode and Arm mode, -except that M-profile processors (`thumbv*m*-*` targets) only support Thumb-mode. - For the `arm*` targets, Thumb-mode code generation can be enabled by using `-C target-feature=+thumb-mode`. Using the unstable `#![feature(arm_target_feature)]`, the attribute `#[target_feature(enable = From 7a5038fb4996a4a36d3625c39d04acf27c06d49b Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 30 Apr 2024 11:17:25 +0200 Subject: [PATCH 200/279] write git-commit-{sha,info} for Cargo in source tarballs This will allow Cargo's build script to pick it up, and populate the correct git information in its version output. --- src/bootstrap/src/core/build_steps/dist.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 770a5cdb232d..5bc9d7615e2b 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -25,7 +25,7 @@ use crate::core::build_steps::llvm; use crate::core::build_steps::tool::{self, Tool}; use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::core::config::TargetSelection; -use crate::utils::channel; +use crate::utils::channel::{self, Info}; use crate::utils::helpers::{exe, is_dylib, output, t, target_supports_cranelift_backend, timeit}; use crate::utils::tarball::{GeneratedTarball, OverlayKind, Tarball}; use crate::{Compiler, DependencyType, Mode, LLVM_TOOLS}; @@ -991,10 +991,17 @@ impl Step for PlainSourceTarball { // Create the version file builder.create(&plain_dst_src.join("version"), &builder.rust_version()); - if let Some(info) = builder.rust_info().info() { - channel::write_commit_hash_file(plain_dst_src, &info.sha); - channel::write_commit_info_file(plain_dst_src, info); - } + + // Create the files containing git info, to ensure --version outputs the same. + let write_git_info = |info: Option<&Info>, path: &Path| { + if let Some(info) = info { + t!(std::fs::create_dir_all(path)); + channel::write_commit_hash_file(path, &info.sha); + channel::write_commit_info_file(path, info); + } + }; + write_git_info(builder.rust_info().info(), plain_dst_src); + write_git_info(builder.cargo_info.info(), &plain_dst_src.join("./src/tools/cargo")); // If we're building from git or tarball sources, we need to vendor // a complete distribution. From 741d40f327291404172b3f35377d8464688c2fe7 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Tue, 30 Apr 2024 15:17:47 +0530 Subject: [PATCH 201/279] Remove redundant union check in `KnownPanicsLint const prop because we are already marking unions `NoPropagation` in `CanConstProp::check()`. That is enough to prevent any attempts at const propagating unions and this second check is not needed. Also improve a comment in `CanConstProp::check()` --- .../src/known_panics_lint.rs | 47 +++++++------------ 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index b2030efca8f0..90c1c7ba63b4 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -583,33 +583,21 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { val.into() } - Aggregate(ref kind, ref fields) => { - // Do not const prop union fields as they can be - // made to produce values that don't match their - // underlying layout's type (see ICE #121534). - // If the last element of the `Adt` tuple - // is `Some` it indicates the ADT is a union - if let AggregateKind::Adt(_, _, _, _, Some(_)) = **kind { - return None; - }; - Value::Aggregate { - fields: fields - .iter() - .map(|field| { - self.eval_operand(field).map_or(Value::Uninit, Value::Immediate) - }) - .collect(), - variant: match **kind { - AggregateKind::Adt(_, variant, _, _, _) => variant, - AggregateKind::Array(_) - | AggregateKind::Tuple - | AggregateKind::RawPtr(_, _) - | AggregateKind::Closure(_, _) - | AggregateKind::Coroutine(_, _) - | AggregateKind::CoroutineClosure(_, _) => VariantIdx::ZERO, - }, - } - } + Aggregate(ref kind, ref fields) => Value::Aggregate { + fields: fields + .iter() + .map(|field| self.eval_operand(field).map_or(Value::Uninit, Value::Immediate)) + .collect(), + variant: match **kind { + AggregateKind::Adt(_, variant, _, _, _) => variant, + AggregateKind::Array(_) + | AggregateKind::Tuple + | AggregateKind::RawPtr(_, _) + | AggregateKind::Closure(_, _) + | AggregateKind::Coroutine(_, _) + | AggregateKind::CoroutineClosure(_, _) => VariantIdx::ZERO, + }, + }, Repeat(ref op, n) => { trace!(?op, ?n); @@ -897,8 +885,9 @@ impl CanConstProp { for (local, val) in cpv.can_const_prop.iter_enumerated_mut() { let ty = body.local_decls[local].ty; if ty.is_union() { - // Do not const prop unions as they can - // ICE during layout calc + // Unions are incompatible with the current implementation of + // const prop because Rust has no concept of an active + // variant of a union *val = ConstPropMode::NoPropagation; } else { match tcx.layout_of(param_env.and(ty)) { From 7032c92b33c978c6a7c24ecca2e02ca27af23147 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Tue, 23 Apr 2024 16:54:44 +0000 Subject: [PATCH 202/279] Add test for efficient codegen of manual `eq` implementations of a small struct --- tests/assembly/manual-eq-efficient.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/assembly/manual-eq-efficient.rs diff --git a/tests/assembly/manual-eq-efficient.rs b/tests/assembly/manual-eq-efficient.rs new file mode 100644 index 000000000000..817ce94f476a --- /dev/null +++ b/tests/assembly/manual-eq-efficient.rs @@ -0,0 +1,22 @@ +// Regression test for #106269 +//@ assembly-output: emit-asm +//@ compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel +//@ only-x86_64 +//@ ignore-sgx + +pub struct S { + a: u8, + b: u8, + c: u8, + d: u8, +} + +// CHECK-LABEL: manual_eq: +#[no_mangle] +pub fn manual_eq(s1: &S, s2: &S) -> bool { + // CHECK: mov [[REG:[a-z0-9]+]], dword ptr [{{[a-z0-9]+}}] + // CHECK-NEXT: cmp [[REG]], dword ptr [{{[a-z0-9]+}}] + // CHECK-NEXT: sete al + // CHECK: ret + s1.a == s2.a && s1.b == s2.b && s1.c == s2.c && s1.d == s2.d +} From e0ec71f154067fe7690b637afd4a80f890169bb5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 30 Apr 2024 17:11:42 +0200 Subject: [PATCH 203/279] Add `normalize()` in run-make `Diff` type --- src/tools/run-make-support/src/diff/mod.rs | 28 +++++++++++++++++--- src/tools/run-make-support/src/diff/tests.rs | 22 +++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/tools/run-make-support/src/diff/mod.rs b/src/tools/run-make-support/src/diff/mod.rs index 54532c6e35ba..332126939c08 100644 --- a/src/tools/run-make-support/src/diff/mod.rs +++ b/src/tools/run-make-support/src/diff/mod.rs @@ -1,3 +1,4 @@ +use regex::Regex; use similar::TextDiff; use std::path::Path; @@ -14,12 +15,19 @@ pub struct Diff { expected_name: Option, actual: Option, actual_name: Option, + normalizers: Vec<(String, String)>, } impl Diff { /// Construct a bare `diff` invocation. pub fn new() -> Self { - Self { expected: None, expected_name: None, actual: None, actual_name: None } + Self { + expected: None, + expected_name: None, + actual: None, + actual_name: None, + normalizers: Vec::new(), + } } /// Specify the expected output for the diff from a file. @@ -58,15 +66,29 @@ impl Diff { self } + /// Specify a regex that should replace text in the "actual" text that will be compared. + pub fn normalize, I: Into>( + &mut self, + regex: R, + replacement: I, + ) -> &mut Self { + self.normalizers.push((regex.into(), replacement.into())); + self + } + /// Executes the diff process, prints any differences to the standard error. #[track_caller] pub fn run(&self) { let expected = self.expected.as_ref().expect("expected text not set"); - let actual = self.actual.as_ref().expect("actual text not set"); + let mut actual = self.actual.as_ref().expect("actual text not set").to_string(); let expected_name = self.expected_name.as_ref().unwrap(); let actual_name = self.actual_name.as_ref().unwrap(); + for (regex, replacement) in &self.normalizers { + let re = Regex::new(regex).expect("bad regex in custom normalization rule"); + actual = re.replace_all(&actual, replacement).into_owned(); + } - let output = TextDiff::from_lines(expected, actual) + let output = TextDiff::from_lines(expected, &actual) .unified_diff() .header(expected_name, actual_name) .to_string(); diff --git a/src/tools/run-make-support/src/diff/tests.rs b/src/tools/run-make-support/src/diff/tests.rs index e6d72544b7eb..286548bef618 100644 --- a/src/tools/run-make-support/src/diff/tests.rs +++ b/src/tools/run-make-support/src/diff/tests.rs @@ -36,4 +36,26 @@ test failed: `EXPECTED_TEXT` is different from `ACTUAL_TEXT` assert_eq!(output.downcast_ref::().unwrap(), expected_output); } + + #[test] + fn test_normalize() { + let expected = " +running 2 tests +.. + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME +"; + let actual = " +running 2 tests +.. + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s +"; + + diff() + .expected_text("EXPECTED_TEXT", expected) + .actual_text("ACTUAL_TEXT", actual) + .normalize(r#"finished in \d+\.\d+s"#, "finished in $$TIME") + .run(); + } } From c2fd6ed2358881ee18f636bf829de4bc180465a6 Mon Sep 17 00:00:00 2001 From: beetrees Date: Tue, 23 Apr 2024 06:41:28 +0100 Subject: [PATCH 204/279] Port repr128-dwarf run-make test to rmake --- Cargo.lock | 1 + src/tools/compiletest/src/runtest.rs | 1 + src/tools/run-make-support/Cargo.toml | 1 + src/tools/run-make-support/src/lib.rs | 1 + .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/repr128-dwarf/Makefile | 16 ---- .../repr128-dwarf/{lib.rs => main.rs} | 5 +- tests/run-make/repr128-dwarf/rmake.rs | 75 +++++++++++++++++++ 8 files changed, 83 insertions(+), 18 deletions(-) delete mode 100644 tests/run-make/repr128-dwarf/Makefile rename tests/run-make/repr128-dwarf/{lib.rs => main.rs} (89%) create mode 100644 tests/run-make/repr128-dwarf/rmake.rs diff --git a/Cargo.lock b/Cargo.lock index 552b446a1e75..4a54dc87862e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3341,6 +3341,7 @@ dependencies = [ name = "run_make_support" version = "0.0.0" dependencies = [ + "gimli", "object 0.34.0", "regex", "wasmparser", diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 1dd639a89188..a16e9c02e2e1 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -3824,6 +3824,7 @@ impl<'test> TestCx<'test> { .arg(format!("-Ldependency={}", &support_lib_deps_deps.to_string_lossy())) .arg("--extern") .arg(format!("run_make_support={}", &support_lib_path.to_string_lossy())) + .arg("--edition=2021") .arg(&self.testpaths.file.join("rmake.rs")) .env("TARGET", &self.config.target) .env("PYTHON", &self.config.python) diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index 3ea35c7940c2..c385ef0f9675 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -7,3 +7,4 @@ edition = "2021" object = "0.34.0" wasmparser = "0.118.2" regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace +gimli = "0.28.1" diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index e723e824ed6c..aeb7417fa69c 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -14,6 +14,7 @@ use std::env; use std::path::{Path, PathBuf}; use std::process::{Command, Output}; +pub use gimli; pub use object; pub use regex; pub use wasmparser; diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index f0ed0ae806fd..139bbe55e9e1 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -238,7 +238,6 @@ run-make/relocation-model/Makefile run-make/relro-levels/Makefile run-make/remap-path-prefix-dwarf/Makefile run-make/remap-path-prefix/Makefile -run-make/repr128-dwarf/Makefile run-make/reproducible-build-2/Makefile run-make/reproducible-build/Makefile run-make/resolve-rename/Makefile diff --git a/tests/run-make/repr128-dwarf/Makefile b/tests/run-make/repr128-dwarf/Makefile deleted file mode 100644 index 3f933042724a..000000000000 --- a/tests/run-make/repr128-dwarf/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# ignore-windows -# This test should be replaced with one in tests/debuginfo once GDB or LLDB support 128-bit -# enums. - -include ../tools.mk - -all: - $(RUSTC) -Cdebuginfo=2 lib.rs -o $(TMPDIR)/repr128.rlib - "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128A $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )" - "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128B $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )" - "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128C $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 )" - "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128D $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff )" - "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128A $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )" - "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128B $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff )" - "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128C $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 )" - "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128D $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 7f )" diff --git a/tests/run-make/repr128-dwarf/lib.rs b/tests/run-make/repr128-dwarf/main.rs similarity index 89% rename from tests/run-make/repr128-dwarf/lib.rs rename to tests/run-make/repr128-dwarf/main.rs index 63675441d4ba..57923a8386db 100644 --- a/tests/run-make/repr128-dwarf/lib.rs +++ b/tests/run-make/repr128-dwarf/main.rs @@ -1,4 +1,3 @@ -#![crate_type = "lib"] #![feature(repr128)] // Use .to_le() to ensure that the bytes are in the same order on both little- and big-endian @@ -21,3 +20,7 @@ pub enum I128Enum { } pub fn f(_: U128Enum, _: I128Enum) {} + +fn main() { + f(U128Enum::U128A, I128Enum::I128A); +} diff --git a/tests/run-make/repr128-dwarf/rmake.rs b/tests/run-make/repr128-dwarf/rmake.rs new file mode 100644 index 000000000000..f6375344f8f2 --- /dev/null +++ b/tests/run-make/repr128-dwarf/rmake.rs @@ -0,0 +1,75 @@ +//@ ignore-windows +// This test should be replaced with one in tests/debuginfo once GDB or LLDB support 128-bit enums. + +extern crate run_make_support; + +use gimli::{AttributeValue, Dwarf, EndianRcSlice, Reader, RunTimeEndian}; +use object::{Object, ObjectSection}; +use run_make_support::{gimli, object, rustc, tmp_dir}; +use std::borrow::Cow; +use std::collections::HashMap; +use std::rc::Rc; + +fn main() { + let output = tmp_dir().join("repr128"); + rustc().input("main.rs").arg("-o").arg(&output).arg("-Cdebuginfo=2").run(); + // Mach-O uses packed debug info + let dsym_location = output + .with_extension("dSYM") + .join("Contents") + .join("Resources") + .join("DWARF") + .join("repr128"); + let output = + std::fs::read(if dsym_location.try_exists().unwrap() { dsym_location } else { output }) + .unwrap(); + let obj = object::File::parse(output.as_slice()).unwrap(); + let endian = if obj.is_little_endian() { RunTimeEndian::Little } else { RunTimeEndian::Big }; + let dwarf = gimli::Dwarf::load(|section| -> Result<_, ()> { + let data = obj.section_by_name(section.name()).map(|s| s.uncompressed_data().unwrap()); + Ok(EndianRcSlice::new(Rc::from(data.unwrap_or_default().as_ref()), endian)) + }) + .unwrap(); + let mut iter = dwarf.units(); + let mut still_to_find = HashMap::from([ + ("U128A", 0_u128), + ("U128B", 1_u128), + ("U128C", u64::MAX as u128 + 1), + ("U128D", u128::MAX), + ("I128A", 0_i128 as u128), + ("I128B", (-1_i128) as u128), + ("I128C", i128::MIN as u128), + ("I128D", i128::MAX as u128), + ]); + while let Some(header) = iter.next().unwrap() { + let unit = dwarf.unit(header).unwrap(); + let mut cursor = unit.entries(); + while let Some((_, entry)) = cursor.next_dfs().unwrap() { + if entry.tag() == gimli::constants::DW_TAG_enumerator { + let name = dwarf + .attr_string( + &unit, + entry.attr(gimli::constants::DW_AT_name).unwrap().unwrap().value(), + ) + .unwrap(); + let name = name.to_string().unwrap(); + if let Some(expected) = still_to_find.remove(name.as_ref()) { + match entry.attr(gimli::constants::DW_AT_const_value).unwrap().unwrap().value() + { + AttributeValue::Block(value) => { + assert_eq!( + value.to_slice().unwrap(), + expected.to_le_bytes().as_slice(), + "{name}" + ); + } + value => panic!("{name}: unexpected DW_AT_const_value of {value:?}"), + } + } + } + } + } + if !still_to_find.is_empty() { + panic!("Didn't find debug entries for {still_to_find:?}"); + } +} From 951e902562de6f052fe8ca77fbc733a752514a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sun, 15 Oct 2023 13:40:17 +0200 Subject: [PATCH 205/279] Normalize trait ref before orphan check & consider ty params in alias types to be uncovered --- compiler/rustc_hir_analysis/messages.ftl | 8 +- .../src/coherence/orphan.rs | 314 ++++++++++++++---- compiler/rustc_hir_analysis/src/errors.rs | 35 +- compiler/rustc_lint_defs/src/builtin.rs | 66 ++++ .../src/traits/coherence.rs | 177 ++++++---- .../rustc_trait_selection/src/traits/mod.rs | 5 +- .../coherence/auxiliary/parametrized-trait.rs | 2 + .../auxiliary/trait-with-assoc-ty.rs | 3 + ...unnormalizable-projection-0.classic.stderr | 19 ++ ...ap-unnormalizable-projection-0.next.stderr | 18 + ...nce-overlap-unnormalizable-projection-0.rs | 42 +++ ...unnormalizable-projection-1.classic.stderr | 19 ++ ...ap-unnormalizable-projection-1.next.stderr | 19 ++ ...nce-overlap-unnormalizable-projection-1.rs | 44 +++ .../orphan-check-projections-covering.rs | 25 ++ .../orphan-check-projections-nested.rs | 23 ++ ...ions-not-covering-ambiguity.classic.stderr | 15 + ...ections-not-covering-ambiguity.next.stderr | 15 + ...heck-projections-not-covering-ambiguity.rs | 29 ++ ...ot-covering-multiple-params.classic.stderr | 26 ++ ...s-not-covering-multiple-params.next.stderr | 26 ++ ...rojections-not-covering-multiple-params.rs | 24 ++ ...ck-projections-not-covering.classic.stderr | 37 +++ ...check-projections-not-covering.next.stderr | 37 +++ .../orphan-check-projections-not-covering.rs | 42 +++ ...ck-projections-unsat-bounds.classic.stderr | 15 + ...check-projections-unsat-bounds.next.stderr | 15 + .../orphan-check-projections-unsat-bounds.rs | 35 ++ .../orphan-check-weak-aliases-covering.rs | 20 ++ ...k-weak-aliases-not-covering.classic.stderr | 12 + ...heck-weak-aliases-not-covering.next.stderr | 12 + .../orphan-check-weak-aliases-not-covering.rs | 19 ++ .../ui/type-alias-impl-trait/coherence.stderr | 2 +- 33 files changed, 1055 insertions(+), 145 deletions(-) create mode 100644 tests/ui/coherence/auxiliary/parametrized-trait.rs create mode 100644 tests/ui/coherence/auxiliary/trait-with-assoc-ty.rs create mode 100644 tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr create mode 100644 tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.next.stderr create mode 100644 tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs create mode 100644 tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr create mode 100644 tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.next.stderr create mode 100644 tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs create mode 100644 tests/ui/coherence/orphan-check-projections-covering.rs create mode 100644 tests/ui/coherence/orphan-check-projections-nested.rs create mode 100644 tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.classic.stderr create mode 100644 tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.next.stderr create mode 100644 tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.rs create mode 100644 tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.classic.stderr create mode 100644 tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.next.stderr create mode 100644 tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.rs create mode 100644 tests/ui/coherence/orphan-check-projections-not-covering.classic.stderr create mode 100644 tests/ui/coherence/orphan-check-projections-not-covering.next.stderr create mode 100644 tests/ui/coherence/orphan-check-projections-not-covering.rs create mode 100644 tests/ui/coherence/orphan-check-projections-unsat-bounds.classic.stderr create mode 100644 tests/ui/coherence/orphan-check-projections-unsat-bounds.next.stderr create mode 100644 tests/ui/coherence/orphan-check-projections-unsat-bounds.rs create mode 100644 tests/ui/coherence/orphan-check-weak-aliases-covering.rs create mode 100644 tests/ui/coherence/orphan-check-weak-aliases-not-covering.classic.stderr create mode 100644 tests/ui/coherence/orphan-check-weak-aliases-not-covering.next.stderr create mode 100644 tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 06b5ee299b85..1d676f68a391 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -486,13 +486,13 @@ hir_analysis_transparent_non_zero_sized_enum = the variant of a transparent {$de hir_analysis_ty_of_assoc_const_binding_note = `{$assoc_const}` has type `{$ty}` -hir_analysis_ty_param_first_local = type parameter `{$param_ty}` must be covered by another type when it appears before the first local type (`{$local_type}`) - .label = type parameter `{$param_ty}` must be covered by another type when it appears before the first local type (`{$local_type}`) +hir_analysis_ty_param_first_local = type parameter `{$param}` must be covered by another type when it appears before the first local type (`{$local_type}`) + .label = type parameter `{$param}` must be covered by another type when it appears before the first local type (`{$local_type}`) .note = implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type .case_note = in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last -hir_analysis_ty_param_some = type parameter `{$param_ty}` must be used as the type parameter for some local type (e.g., `MyStruct<{$param_ty}>`) - .label = type parameter `{$param_ty}` must be used as the type parameter for some local type +hir_analysis_ty_param_some = type parameter `{$param}` must be used as the type parameter for some local type (e.g., `MyStruct<{$param}>`) + .label = type parameter `{$param}` must be used as the type parameter for some local type .note = implementing a foreign trait is only possible if at least one of the types for which it is implemented is local .only_note = only traits defined in the current crate can be implemented for a type parameter diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 5585d2e069c5..a256d11fd5aa 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -2,14 +2,20 @@ //! crate or pertains to a type defined in this crate. use crate::errors; -use rustc_errors::ErrorGuaranteed; -use rustc_hir as hir; -use rustc_middle::ty::{self, AliasKind, TyCtxt, TypeVisitableExt}; -use rustc_span::def_id::LocalDefId; -use rustc_span::Span; -use rustc_trait_selection::traits::{self, IsFirstInputType}; -#[instrument(skip(tcx), level = "debug")] +use rustc_data_structures::fx::FxIndexSet; +use rustc_errors::ErrorGuaranteed; +use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; +use rustc_lint_defs::builtin::UNCOVERED_PARAM_IN_PROJECTION; +use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; +use rustc_span::def_id::{DefId, LocalDefId}; +use rustc_trait_selection::traits::{self, IsFirstInputType, UncoveredTyParams}; +use rustc_trait_selection::traits::{OrphanCheckErr, OrphanCheckMode}; +use rustc_trait_selection::traits::{StructurallyNormalizeExt, TraitEngineExt}; + +#[instrument(level = "debug", skip(tcx))] pub(crate) fn orphan_check_impl( tcx: TyCtxt<'_>, impl_def_id: LocalDefId, @@ -17,31 +23,23 @@ pub(crate) fn orphan_check_impl( let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity(); trait_ref.error_reported()?; - let trait_def_id = trait_ref.def_id; - - match traits::orphan_check(tcx, impl_def_id.to_def_id()) { + match orphan_check(tcx, impl_def_id, OrphanCheckMode::Proper) { Ok(()) => {} - Err(err) => { - let item = tcx.hir().expect_item(impl_def_id); - let hir::ItemKind::Impl(impl_) = item.kind else { - bug!("{:?} is not an impl: {:?}", impl_def_id, item); - }; - let tr = impl_.of_trait.as_ref().unwrap(); - let sp = tcx.def_span(impl_def_id); - - emit_orphan_check_error( - tcx, - sp, - item.span, - tr.path.span, - trait_ref, - impl_.self_ty.span, - impl_.generics, - err, - )? - } + Err(err) => match orphan_check(tcx, impl_def_id, OrphanCheckMode::Compat) { + Ok(()) => match err { + OrphanCheckErr::UncoveredTyParams(uncovered_ty_params) => { + lint_uncovered_ty_params(tcx, uncovered_ty_params, impl_def_id) + } + OrphanCheckErr::NonLocalInputType(_) => { + bug!("orphanck: shouldn't've gotten non-local input tys in compat mode") + } + }, + Err(err) => return Err(emit_orphan_check_error(tcx, trait_ref, impl_def_id, err)), + }, } + let trait_def_id = trait_ref.def_id; + // In addition to the above rules, we restrict impls of auto traits // so that they can only be implemented on nominal types, such as structs, // enums or foreign types. To see why this restriction exists, consider the @@ -186,13 +184,13 @@ pub(crate) fn orphan_check_impl( // type This = T; // } // impl AutoTrait for ::This {} - AliasKind::Projection => "associated type", + ty::Projection => "associated type", // type Foo = (impl Sized, bool) // impl AutoTrait for Foo {} - AliasKind::Weak => "type alias", + ty::Weak => "type alias", // type Opaque = impl Trait; // impl AutoTrait for Opaque {} - AliasKind::Opaque => "opaque type", + ty::Opaque => "opaque type", // ``` // struct S(T); // impl S { @@ -201,7 +199,7 @@ pub(crate) fn orphan_check_impl( // impl AutoTrait for S::This {} // ``` // FIXME(inherent_associated_types): The example code above currently leads to a cycle - AliasKind::Inherent => "associated type", + ty::Inherent => "associated type", }; (LocalImpl::Disallow { problematic_kind }, NonlocalImpl::DisallowOther) } @@ -275,34 +273,125 @@ pub(crate) fn orphan_check_impl( Ok(()) } +/// Checks the coherence orphan rules. +/// +/// `impl_def_id` should be the `DefId` of a trait impl. +/// +/// To pass, either the trait must be local, or else two conditions must be satisfied: +/// +/// 1. All type parameters in `Self` must be "covered" by some local type constructor. +/// 2. Some local type must appear in `Self`. +#[instrument(level = "debug", skip(tcx), ret)] +fn orphan_check<'tcx>( + tcx: TyCtxt<'tcx>, + impl_def_id: LocalDefId, + mode: OrphanCheckMode, +) -> Result<(), OrphanCheckErr<'tcx, FxIndexSet>> { + // We only accept this routine to be invoked on implementations + // of a trait, not inherent implementations. + let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); + debug!(trait_ref = ?trait_ref.skip_binder()); + + // If the *trait* is local to the crate, ok. + if let Some(def_id) = trait_ref.skip_binder().def_id.as_local() { + debug!("trait {def_id:?} is local to current crate"); + return Ok(()); + } + + // (1) Instantiate all generic params with fresh inference vars. + let infcx = tcx.infer_ctxt().intercrate(true).build(); + let cause = traits::ObligationCause::dummy(); + let args = infcx.fresh_args_for_item(cause.span, impl_def_id.to_def_id()); + let trait_ref = trait_ref.instantiate(tcx, args); + + let lazily_normalize_ty = |user_ty: Ty<'tcx>| { + let ty::Alias(..) = user_ty.kind() else { return Ok(user_ty) }; + + let ocx = traits::ObligationCtxt::new(&infcx); + let ty = ocx.normalize(&cause, ty::ParamEnv::empty(), user_ty); + let ty = infcx.resolve_vars_if_possible(ty); + let errors = ocx.select_where_possible(); + if !errors.is_empty() { + return Ok(user_ty); + } + + let ty = if infcx.next_trait_solver() { + let mut fulfill_cx = >::new(&infcx); + infcx + .at(&cause, ty::ParamEnv::empty()) + .structurally_normalize(ty, &mut *fulfill_cx) + .map(|ty| infcx.resolve_vars_if_possible(ty)) + .unwrap_or(ty) + } else { + ty + }; + + Ok(ty) + }; + + let Ok(result) = traits::orphan_check_trait_ref::( + trait_ref, + traits::InCrate::Local { mode }, + lazily_normalize_ty, + ) else { + unreachable!() + }; + + // (2) Try to map the remaining inference vars back to generic params. + result.map_err(|err| match err { + OrphanCheckErr::UncoveredTyParams(UncoveredTyParams { uncovered, local_ty }) => { + let mut collector = + UncoveredTyParamCollector { infcx: &infcx, uncovered_params: Default::default() }; + uncovered.visit_with(&mut collector); + // FIXME(fmease): This is very likely reachable. + debug_assert!(!collector.uncovered_params.is_empty()); + + OrphanCheckErr::UncoveredTyParams(UncoveredTyParams { + uncovered: collector.uncovered_params, + local_ty, + }) + } + OrphanCheckErr::NonLocalInputType(tys) => { + let generics = tcx.generics_of(impl_def_id); + let tys = tys + .into_iter() + .map(|(ty, is_target_ty)| { + (ty.fold_with(&mut TyVarReplacer { infcx: &infcx, generics }), is_target_ty) + }) + .collect(); + OrphanCheckErr::NonLocalInputType(tys) + } + }) +} + fn emit_orphan_check_error<'tcx>( tcx: TyCtxt<'tcx>, - sp: Span, - full_impl_span: Span, - trait_span: Span, trait_ref: ty::TraitRef<'tcx>, - self_ty_span: Span, - generics: &hir::Generics<'tcx>, - err: traits::OrphanCheckErr<'tcx>, -) -> Result { - let self_ty = trait_ref.self_ty(); - Err(match err { + impl_def_id: LocalDefId, + err: traits::OrphanCheckErr<'tcx, FxIndexSet>, +) -> ErrorGuaranteed { + match err { traits::OrphanCheckErr::NonLocalInputType(tys) => { - let mut diag = tcx.dcx().create_err(match self_ty.kind() { - ty::Adt(..) => errors::OnlyCurrentTraits::Outside { span: sp, note: () }, - _ if self_ty.is_primitive() => { - errors::OnlyCurrentTraits::Primitive { span: sp, note: () } + let item = tcx.hir().expect_item(impl_def_id); + let impl_ = item.expect_impl(); + let hir_trait_ref = impl_.of_trait.as_ref().unwrap(); + + let span = tcx.def_span(impl_def_id); + let mut diag = tcx.dcx().create_err(match trait_ref.self_ty().kind() { + ty::Adt(..) => errors::OnlyCurrentTraits::Outside { span, note: () }, + _ if trait_ref.self_ty().is_primitive() => { + errors::OnlyCurrentTraits::Primitive { span, note: () } } - _ => errors::OnlyCurrentTraits::Arbitrary { span: sp, note: () }, + _ => errors::OnlyCurrentTraits::Arbitrary { span, note: () }, }); for &(mut ty, is_target_ty) in &tys { let span = if matches!(is_target_ty, IsFirstInputType::Yes) { // Point at `D` in `impl for C in D` - self_ty_span + impl_.self_ty.span } else { // Point at `C` in `impl for C in D` - trait_span + hir_trait_ref.path.span }; ty = tcx.erase_regions(ty); @@ -354,12 +443,12 @@ fn emit_orphan_check_error<'tcx>( diag.subdiagnostic(tcx.dcx(), errors::OnlyCurrentTraitsOpaque { span }); } ty::RawPtr(ptr_ty, mutbl) => { - if !self_ty.has_param() { + if !trait_ref.self_ty().has_param() { diag.subdiagnostic( tcx.dcx(), errors::OnlyCurrentTraitsPointerSugg { - wrapper_span: self_ty_span, - struct_span: full_impl_span.shrink_to_lo(), + wrapper_span: impl_.self_ty.span, + struct_span: item.span.shrink_to_lo(), mut_key: mutbl.prefix_str(), ptr_ty, }, @@ -387,23 +476,112 @@ fn emit_orphan_check_error<'tcx>( diag.emit() } - traits::OrphanCheckErr::UncoveredTy(param_ty, local_type) => { - let mut sp = sp; - for param in generics.params { - if param.name.ident().to_string() == param_ty.to_string() { - sp = param.span; - } - } + traits::OrphanCheckErr::UncoveredTyParams(UncoveredTyParams { uncovered, local_ty }) => { + let mut reported = None; + for param_def_id in uncovered { + let span = tcx.def_ident_span(param_def_id).unwrap(); + let name = tcx.item_name(param_def_id); - match local_type { - Some(local_type) => tcx.dcx().emit_err(errors::TyParamFirstLocal { - span: sp, - note: (), - param_ty, - local_type, - }), - None => tcx.dcx().emit_err(errors::TyParamSome { span: sp, note: (), param_ty }), + reported.get_or_insert(match local_ty { + Some(local_type) => tcx.dcx().emit_err(errors::TyParamFirstLocal { + span, + note: (), + param: name, + local_type, + }), + None => tcx.dcx().emit_err(errors::TyParamSome { span, note: (), param: name }), + }); } + reported.unwrap() // FIXME(fmease): This is very likely reachable. } - }) + } +} + +fn lint_uncovered_ty_params<'tcx>( + tcx: TyCtxt<'tcx>, + UncoveredTyParams { uncovered, local_ty }: UncoveredTyParams<'tcx, FxIndexSet>, + impl_def_id: LocalDefId, +) { + let hir_id = tcx.local_def_id_to_hir_id(impl_def_id); + + for param_def_id in uncovered { + let span = tcx.def_ident_span(param_def_id).unwrap(); + let name = tcx.item_name(param_def_id); + + match local_ty { + Some(local_type) => tcx.emit_node_span_lint( + UNCOVERED_PARAM_IN_PROJECTION, + hir_id, + span, + errors::TyParamFirstLocalLint { span, note: (), param: name, local_type }, + ), + None => tcx.emit_node_span_lint( + UNCOVERED_PARAM_IN_PROJECTION, + hir_id, + span, + errors::TyParamSomeLint { span, note: (), param: name }, + ), + }; + } +} + +struct UncoveredTyParamCollector<'cx, 'tcx> { + infcx: &'cx InferCtxt<'tcx>, + uncovered_params: FxIndexSet, +} + +impl<'tcx> TypeVisitor> for UncoveredTyParamCollector<'_, 'tcx> { + fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { + if !ty.has_type_flags(ty::TypeFlags::HAS_TY_INFER) { + return; + } + let Some(origin) = self.infcx.type_var_origin(ty) else { + return ty.super_visit_with(self); + }; + if let Some(def_id) = origin.param_def_id { + self.uncovered_params.insert(def_id); + } + } + + fn visit_const(&mut self, ct: ty::Const<'tcx>) -> Self::Result { + if ct.has_type_flags(ty::TypeFlags::HAS_TY_INFER) { + ct.super_visit_with(self) + } + } +} + +struct TyVarReplacer<'cx, 'tcx> { + infcx: &'cx InferCtxt<'tcx>, + generics: &'tcx ty::Generics, +} + +impl<'cx, 'tcx> TypeFolder> for TyVarReplacer<'cx, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { + self.infcx.tcx + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + if !ty.has_type_flags(ty::TypeFlags::HAS_TY_INFER) { + return ty; + } + let Some(origin) = self.infcx.type_var_origin(ty) else { + return ty.super_fold_with(self); + }; + if let Some(def_id) = origin.param_def_id { + // The generics of an `impl` don't have a parent, we can index directly. + let index = self.generics.param_def_id_to_index[&def_id]; + let name = self.generics.params[index as usize].name; + + Ty::new_param(self.infcx.tcx, index, name) + } else { + ty + } + } + + fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { + if !ct.has_type_flags(ty::TypeFlags::HAS_TY_INFER) { + return ct; + } + ct.super_fold_with(self) + } } diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 867ee772a30a..ccc7dbc150b2 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1355,29 +1355,54 @@ pub struct CrossCrateTraitsDefined { pub traits: String, } +// FIXME(fmease): Deduplicate: + #[derive(Diagnostic)] #[diag(hir_analysis_ty_param_first_local, code = E0210)] #[note] -pub struct TyParamFirstLocal<'a> { +pub struct TyParamFirstLocal<'tcx> { #[primary_span] #[label] pub span: Span, #[note(hir_analysis_case_note)] pub note: (), - pub param_ty: Ty<'a>, - pub local_type: Ty<'a>, + pub param: Symbol, + pub local_type: Ty<'tcx>, +} + +#[derive(LintDiagnostic)] +#[diag(hir_analysis_ty_param_first_local, code = E0210)] +#[note] +pub struct TyParamFirstLocalLint<'tcx> { + #[label] + pub span: Span, + #[note(hir_analysis_case_note)] + pub note: (), + pub param: Symbol, + pub local_type: Ty<'tcx>, } #[derive(Diagnostic)] #[diag(hir_analysis_ty_param_some, code = E0210)] #[note] -pub struct TyParamSome<'a> { +pub struct TyParamSome { #[primary_span] #[label] pub span: Span, #[note(hir_analysis_only_note)] pub note: (), - pub param_ty: Ty<'a>, + pub param: Symbol, +} + +#[derive(LintDiagnostic)] +#[diag(hir_analysis_ty_param_some, code = E0210)] +#[note] +pub struct TyParamSomeLint { + #[label] + pub span: Span, + #[note(hir_analysis_only_note)] + pub note: (), + pub param: Symbol, } #[derive(Diagnostic)] diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index e74cc388cab4..86a0f33a8d15 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -101,6 +101,7 @@ declare_lint_pass! { TYVAR_BEHIND_RAW_POINTER, UNCONDITIONAL_PANIC, UNCONDITIONAL_RECURSION, + UNCOVERED_PARAM_IN_PROJECTION, UNDEFINED_NAKED_FUNCTION_ABI, UNEXPECTED_CFGS, UNFULFILLED_LINT_EXPECTATIONS, @@ -4741,3 +4742,68 @@ declare_lint! { }; crate_level_only } + +declare_lint! { + /// The `uncovered_param_in_projection` lint detects a violation of one of Rust's orphan rules for + /// foreign trait implementations that concerns the use of type parameters inside trait associated + /// type paths ("projections") whose output may not be a local type that is mistakenly considered + /// to "cover" said parameters which is **unsound** and which may be rejected by a future version + /// of the compiler. + /// + /// Originally reported in [#99554]. + /// + /// [#99554]: https://github.com/rust-lang/rust/issues/99554 + /// + /// ### Example + /// + /// ```rust,ignore (dependent) + /// // dependency.rs + /// #![crate_type = "lib"] + /// + /// pub trait Trait {} + /// ``` + /// + /// ```edition2021,ignore (needs dependency) + /// // dependent.rs + /// trait Identity { + /// type Output; + /// } + /// + /// impl Identity for T { + /// type Output = T; + /// } + /// + /// struct Local; + /// + /// impl dependency::Trait for ::Output {} + /// + /// fn main() {} + /// ``` + /// + /// This will produce: + /// + /// ```text + /// warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + /// --> dependent.rs:11:6 + /// | + /// 11 | impl dependency::Trait for ::Output {} + /// | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + /// | + /// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + /// = note: for more information, see issue #124559 + /// = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + /// = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + /// = note: `#[warn(uncovered_param_in_projection)]` on by default + /// ``` + /// + /// ### Explanation + /// + /// FIXME(fmease): Write explainer. + pub UNCOVERED_PARAM_IN_PROJECTION, + Warn, + "impl contains type parameters that are not covered", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, + reference: "issue #124559 ", + }; +} diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 36028b516591..b06e3a7cff7c 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -20,15 +20,15 @@ use crate::traits::{ use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{Diag, EmissionGuarantee}; use rustc_hir::def::DefKind; -use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_hir::def_id::DefId; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::{util, FulfillmentErrorCode, TraitEngine, TraitEngineExt}; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal}; use rustc_middle::traits::specialization_graph::OverlapMode; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; -use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor}; +use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::DUMMY_SP; use std::fmt::Debug; @@ -36,14 +36,28 @@ use std::ops::ControlFlow; use super::error_reporting::suggest_new_overflow_limit; -/// Whether we do the orphan check relative to this crate or -/// to some remote crate. +/// Whether we do the orphan check relative to this crate or to some remote crate. #[derive(Copy, Clone, Debug)] -enum InCrate { - Local, +pub enum InCrate { + Local { mode: OrphanCheckMode }, Remote, } +#[derive(Copy, Clone, Debug)] +pub enum OrphanCheckMode { + /// Proper orphan check. + Proper, + /// Improper orphan check for backward compatibility. + /// + /// In this mode, type params inside projections are considered to be covered + /// even if the projection may normalize to a type that doesn't actually cover + /// them. This is unsound. See also [#124559] and [#99554]. + /// + /// [#124559]: https://github.com/rust-lang/rust/issues/124559 + /// [#99554]: https://github.com/rust-lang/rust/issues/99554 + Compat, +} + #[derive(Debug, Copy, Clone)] pub enum Conflict { Upstream, @@ -633,7 +647,13 @@ pub fn trait_ref_is_knowable<'tcx, E: Debug>( // and if we are an intermediate owner, then we don't care // about future-compatibility, which means that we're OK if // we are an owner. - if orphan_check_trait_ref(trait_ref, InCrate::Local, &mut lazily_normalize_ty)?.is_ok() { + if orphan_check_trait_ref( + trait_ref, + InCrate::Local { mode: OrphanCheckMode::Proper }, + &mut lazily_normalize_ty, + )? + .is_ok() + { Ok(Ok(())) } else { Ok(Err(Conflict::Upstream)) @@ -644,7 +664,7 @@ pub fn trait_ref_is_local_or_fundamental<'tcx>( tcx: TyCtxt<'tcx>, trait_ref: ty::TraitRef<'tcx>, ) -> bool { - trait_ref.def_id.krate == LOCAL_CRATE || tcx.has_attr(trait_ref.def_id, sym::fundamental) + trait_ref.def_id.is_local() || tcx.has_attr(trait_ref.def_id, sym::fundamental) } #[derive(Debug, Copy, Clone)] @@ -663,31 +683,15 @@ impl From for IsFirstInputType { } #[derive(Debug)] -pub enum OrphanCheckErr<'tcx> { +pub enum OrphanCheckErr<'tcx, T> { NonLocalInputType(Vec<(Ty<'tcx>, IsFirstInputType)>), - UncoveredTy(Ty<'tcx>, Option>), + UncoveredTyParams(UncoveredTyParams<'tcx, T>), } -/// Checks the coherence orphan rules. `impl_def_id` should be the -/// `DefId` of a trait impl. To pass, either the trait must be local, or else -/// two conditions must be satisfied: -/// -/// 1. All type parameters in `Self` must be "covered" by some local type constructor. -/// 2. Some local type must appear in `Self`. -#[instrument(level = "debug", skip(tcx), ret)] -pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanCheckErr<'_>> { - // We only except this routine to be invoked on implementations - // of a trait, not inherent implementations. - let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity(); - debug!(?trait_ref); - - // If the *trait* is local to the crate, ok. - if trait_ref.def_id.is_local() { - debug!("trait {:?} is local to current crate", trait_ref.def_id); - return Ok(()); - } - - orphan_check_trait_ref::(trait_ref, InCrate::Local, |ty| Ok(ty)).unwrap() +#[derive(Debug)] +pub struct UncoveredTyParams<'tcx, T> { + pub uncovered: T, + pub local_ty: Option>, } /// Checks whether a trait-ref is potentially implementable by a crate. @@ -735,6 +739,9 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe /// To check that a local impl follows the orphan rules, we check it in /// InCrate::Local mode, using type parameters for the "generic" types. /// +/// In InCrate::Local mode the orphan check succeeds if the current crate +/// is definitely allowed to implement the given trait (no false positives). +/// /// 2. They ground negative reasoning for coherence. If a user wants to /// write both a conditional blanket impl and a specific impl, we need to /// make sure they do not overlap. For example, if we write @@ -753,6 +760,9 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe /// try to implement this trait-ref. To check for this, we use InCrate::Remote /// mode. That is sound because we already know all the impls from known crates. /// +/// In InCrate::Remote mode the orphan check succeeds if a foreign crate +/// *could* implement the given trait (no false negatives). +/// /// 3. For non-`#[fundamental]` traits, they guarantee that parent crates can /// add "non-blanket" impls without breaking negative reasoning in dependent /// crates. This is the "rebalancing coherence" (RFC 1023) restriction. @@ -777,11 +787,11 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe /// Note that this function is never called for types that have both type /// parameters and inference variables. #[instrument(level = "trace", skip(lazily_normalize_ty), ret)] -fn orphan_check_trait_ref<'tcx, E: Debug>( +pub fn orphan_check_trait_ref<'tcx, E: Debug>( trait_ref: ty::TraitRef<'tcx>, in_crate: InCrate, lazily_normalize_ty: impl FnMut(Ty<'tcx>) -> Result, E>, -) -> Result>, E> { +) -> Result>>, E> { if trait_ref.has_infer() && trait_ref.has_param() { bug!( "can't orphan check a trait ref with both params and inference variables {:?}", @@ -790,21 +800,28 @@ fn orphan_check_trait_ref<'tcx, E: Debug>( } let mut checker = OrphanChecker::new(in_crate, lazily_normalize_ty); + + // Does there exist some local type after the `ParamTy`. + let search_first_local_ty = |checker: &mut OrphanChecker<'tcx, _>| { + checker.search_first_local_ty = true; + match trait_ref.visit_with(checker).break_value() { + Some(OrphanCheckEarlyExit::LocalTy(local_ty)) => Some(local_ty), + _ => None, + } + }; + Ok(match trait_ref.visit_with(&mut checker) { ControlFlow::Continue(()) => Err(OrphanCheckErr::NonLocalInputType(checker.non_local_tys)), - ControlFlow::Break(OrphanCheckEarlyExit::NormalizationFailure(err)) => return Err(err), - ControlFlow::Break(OrphanCheckEarlyExit::ParamTy(ty)) => { - // Does there exist some local type after the `ParamTy`. - checker.search_first_local_ty = true; - if let Some(OrphanCheckEarlyExit::LocalTy(local_ty)) = - trait_ref.visit_with(&mut checker).break_value() - { - Err(OrphanCheckErr::UncoveredTy(ty, Some(local_ty))) - } else { - Err(OrphanCheckErr::UncoveredTy(ty, None)) + ControlFlow::Break(residual) => match residual { + OrphanCheckEarlyExit::NormalizationFailure(err) => return Err(err), + OrphanCheckEarlyExit::UncoveredTyParam(ty) => { + Err(OrphanCheckErr::UncoveredTyParams(UncoveredTyParams { + uncovered: ty, + local_ty: search_first_local_ty(&mut checker), + })) } - } - ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(_)) => Ok(()), + OrphanCheckEarlyExit::LocalTy(_) => Ok(()), + }, }) } @@ -812,8 +829,7 @@ struct OrphanChecker<'tcx, F> { in_crate: InCrate, in_self_ty: bool, lazily_normalize_ty: F, - /// Ignore orphan check failures and exclusively search for the first - /// local type. + /// Ignore orphan check failures and exclusively search for the first local type. search_first_local_ty: bool, non_local_tys: Vec<(Ty<'tcx>, IsFirstInputType)>, } @@ -837,17 +853,20 @@ where ControlFlow::Continue(()) } - fn found_param_ty(&mut self, t: Ty<'tcx>) -> ControlFlow> { + fn found_uncovered_ty_param( + &mut self, + ty: Ty<'tcx>, + ) -> ControlFlow> { if self.search_first_local_ty { - ControlFlow::Continue(()) - } else { - ControlFlow::Break(OrphanCheckEarlyExit::ParamTy(t)) + return ControlFlow::Continue(()); } + + ControlFlow::Break(OrphanCheckEarlyExit::UncoveredTyParam(ty)) } fn def_id_is_local(&mut self, def_id: DefId) -> bool { match self.in_crate { - InCrate::Local => def_id.is_local(), + InCrate::Local { .. } => def_id.is_local(), InCrate::Remote => false, } } @@ -855,7 +874,7 @@ where enum OrphanCheckEarlyExit<'tcx, E> { NormalizationFailure(E), - ParamTy(Ty<'tcx>), + UncoveredTyParam(Ty<'tcx>), LocalTy(Ty<'tcx>), } @@ -864,14 +883,15 @@ where F: FnMut(Ty<'tcx>) -> Result, E>, { type Result = ControlFlow>; + fn visit_region(&mut self, _r: ty::Region<'tcx>) -> Self::Result { ControlFlow::Continue(()) } fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { - // Need to lazily normalize here in with `-Znext-solver=coherence`. let ty = match (self.lazily_normalize_ty)(ty) { - Ok(ty) => ty, + Ok(norm_ty) if norm_ty.is_ty_var() => ty, + Ok(norm_ty) => norm_ty, Err(err) => return ControlFlow::Break(OrphanCheckEarlyExit::NormalizationFailure(err)), }; @@ -889,19 +909,46 @@ where | ty::Slice(..) | ty::RawPtr(..) | ty::Never - | ty::Tuple(..) - | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..) => { - self.found_non_local_ty(ty) + | ty::Tuple(..) => self.found_non_local_ty(ty), + + ty::Param(..) => bug!("unexpected ty param"), + + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => { + match self.in_crate { + InCrate::Local { .. } => self.found_uncovered_ty_param(ty), + // The inference variable might be unified with a local + // type in that remote crate. + InCrate::Remote => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)), + } } - ty::Param(..) => self.found_param_ty(ty), + ty::Alias(kind @ (ty::Projection | ty::Inherent | ty::Weak), ..) => { + if ty.has_type_flags(ty::TypeFlags::HAS_TY_PARAM) { + bug!("unexpected ty param in alias ty"); + } - ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => match self.in_crate { - InCrate::Local => self.found_non_local_ty(ty), - // The inference variable might be unified with a local - // type in that remote crate. - InCrate::Remote => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)), - }, + if ty.has_type_flags( + ty::TypeFlags::HAS_TY_PLACEHOLDER + | ty::TypeFlags::HAS_TY_BOUND + | ty::TypeFlags::HAS_TY_INFER, + ) { + match self.in_crate { + InCrate::Local { mode } => match kind { + ty::Projection if let OrphanCheckMode::Compat = mode => { + ControlFlow::Continue(()) + } + _ => self.found_uncovered_ty_param(ty), + }, + InCrate::Remote => { + // The inference variable might be unified with a local + // type in that remote crate. + ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) + } + } + } else { + ControlFlow::Continue(()) + } + } // For fundamental types, we just look inside of them. ty::Ref(_, ty, _) => ty.visit_with(self), diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 88ebf8754d3c..56f8b4b9cdb8 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -41,8 +41,9 @@ use rustc_span::Span; use std::fmt::Debug; use std::ops::ControlFlow; -pub use self::coherence::{add_placeholder_note, orphan_check, overlapping_impls}; -pub use self::coherence::{IsFirstInputType, OrphanCheckErr, OverlapResult}; +pub use self::coherence::{add_placeholder_note, orphan_check_trait_ref, overlapping_impls}; +pub use self::coherence::{InCrate, IsFirstInputType, UncoveredTyParams}; +pub use self::coherence::{OrphanCheckErr, OrphanCheckMode, OverlapResult}; pub use self::engine::{ObligationCtxt, TraitEngineExt}; pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation}; pub use self::normalize::NormalizeExt; diff --git a/tests/ui/coherence/auxiliary/parametrized-trait.rs b/tests/ui/coherence/auxiliary/parametrized-trait.rs new file mode 100644 index 000000000000..88a3d5cd52dc --- /dev/null +++ b/tests/ui/coherence/auxiliary/parametrized-trait.rs @@ -0,0 +1,2 @@ +pub trait Trait0 {} +pub trait Trait1 {} diff --git a/tests/ui/coherence/auxiliary/trait-with-assoc-ty.rs b/tests/ui/coherence/auxiliary/trait-with-assoc-ty.rs new file mode 100644 index 000000000000..d49538de580d --- /dev/null +++ b/tests/ui/coherence/auxiliary/trait-with-assoc-ty.rs @@ -0,0 +1,3 @@ +pub trait Trait { + type Assoc; +} diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr new file mode 100644 index 000000000000..2ffb6000ec82 --- /dev/null +++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr @@ -0,0 +1,19 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `Box<_>` + --> $DIR/coherence-overlap-unnormalizable-projection-0.rs:27:1 + | +LL | / impl Trait for T +LL | | where +LL | | T: 'static, +LL | | for<'a> T: WithAssoc<'a>, +LL | | for<'a> >::Assoc: WhereBound, + | |____________________________________________________- first implementation here +... +LL | impl Trait for Box {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>` + | + = note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>` + = note: downstream crates may implement trait `WhereBound` for type ` as WithAssoc<'a>>::Assoc` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.next.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.next.stderr new file mode 100644 index 000000000000..99abdf65abd5 --- /dev/null +++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.next.stderr @@ -0,0 +1,18 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `Box<_>` + --> $DIR/coherence-overlap-unnormalizable-projection-0.rs:27:1 + | +LL | / impl Trait for T +LL | | where +LL | | T: 'static, +LL | | for<'a> T: WithAssoc<'a>, +LL | | for<'a> >::Assoc: WhereBound, + | |____________________________________________________- first implementation here +... +LL | impl Trait for Box {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>` + | + = note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs new file mode 100644 index 000000000000..b8b6d8846ef7 --- /dev/null +++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs @@ -0,0 +1,42 @@ +// Regression test for soundness issue #114061: +// "Coherence incorrectly considers `unnormalizable_projection: Trait` to not hold even if it could" +#![crate_type = "lib"] + +//@ revisions: classic next +//@[next] compile-flags: -Znext-solver + +trait WhereBound {} +impl WhereBound for () {} + + +pub trait WithAssoc<'a> { + type Assoc; +} + +// These two impls of `Trait` overlap: + +pub trait Trait {} +impl Trait for T +where + T: 'static, + for<'a> T: WithAssoc<'a>, + for<'a> >::Assoc: WhereBound, +{ +} + +impl Trait for Box {} //~ ERROR conflicting implementations of trait `Trait` for type `Box<_>` + +// A downstream crate could write: +// +// use upstream::*; +// +// struct Local; +// impl WithAssoc<'_> for Box { +// type Assoc = (); +// } +// +// fn impls_trait() {} +// +// fn main() { +// impls_trait::>(); +// } diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr new file mode 100644 index 000000000000..49b236f9d2aa --- /dev/null +++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr @@ -0,0 +1,19 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `Box<_>` + --> $DIR/coherence-overlap-unnormalizable-projection-1.rs:26:1 + | +LL | / impl Trait for T +LL | | where +LL | | T: 'static, +LL | | for<'a> T: WithAssoc<'a>, +LL | | for<'a> Box<>::Assoc>: WhereBound, + | |_________________________________________________________- first implementation here +... +LL | impl Trait for Box {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>` + | + = note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>` + = note: downstream crates may implement trait `WhereBound` for type `std::boxed::Box< as WithAssoc<'a>>::Assoc>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.next.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.next.stderr new file mode 100644 index 000000000000..49b236f9d2aa --- /dev/null +++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.next.stderr @@ -0,0 +1,19 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `Box<_>` + --> $DIR/coherence-overlap-unnormalizable-projection-1.rs:26:1 + | +LL | / impl Trait for T +LL | | where +LL | | T: 'static, +LL | | for<'a> T: WithAssoc<'a>, +LL | | for<'a> Box<>::Assoc>: WhereBound, + | |_________________________________________________________- first implementation here +... +LL | impl Trait for Box {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>` + | + = note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>` + = note: downstream crates may implement trait `WhereBound` for type `std::boxed::Box< as WithAssoc<'a>>::Assoc>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs new file mode 100644 index 000000000000..8eeadb3dc754 --- /dev/null +++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs @@ -0,0 +1,44 @@ +// Regression test for soundness issue #114061: +// "Coherence incorrectly considers `unnormalizable_projection: Trait` to not hold even if it could" +#![crate_type = "lib"] + +//@ revisions: classic next +//@[next] compile-flags: -Znext-solver + +pub trait WhereBound {} +impl WhereBound for () {} + +pub trait WithAssoc<'a> { + type Assoc; +} + +// These two impls of `Trait` overlap: + +pub trait Trait {} +impl Trait for T +where + T: 'static, + for<'a> T: WithAssoc<'a>, + for<'a> Box<>::Assoc>: WhereBound, +{ +} + +impl Trait for Box {} //~ ERROR conflicting implementations of trait `Trait` for type `Box<_>` + +// A downstream crate could write: +// +// +// use upstream::*; +// +// struct Local; +// impl WithAssoc<'_> for Box { +// type Assoc = Local; +// } +// +// impl WhereBound for Box {} +// +// fn impls_trait() {} +// +// fn main() { +// impls_trait::>(); +// } diff --git a/tests/ui/coherence/orphan-check-projections-covering.rs b/tests/ui/coherence/orphan-check-projections-covering.rs new file mode 100644 index 000000000000..ae1917ec161f --- /dev/null +++ b/tests/ui/coherence/orphan-check-projections-covering.rs @@ -0,0 +1,25 @@ +// Projections cover type parameters if they normalize to a (local) type that covers them. +// This ensures that we don't perform an overly strict check on +// projections like in closed PR #100555 which did a syntactic +// check for type parameters in projections without normalizing +// first which would've lead to real-word regressions. + +//@ check-pass +//@ revisions: classic next +//@[next] compile-flags: -Znext-solver + +//@ aux-crate:foreign=parametrized-trait.rs +//@ edition:2021 + +trait Project { type Output; } + +impl Project for Wrapper { + type Output = Local; +} + +struct Wrapper(T); +struct Local; + +impl foreign::Trait1 for as Project>::Output {} + +fn main() {} diff --git a/tests/ui/coherence/orphan-check-projections-nested.rs b/tests/ui/coherence/orphan-check-projections-nested.rs new file mode 100644 index 000000000000..ec244a8005b1 --- /dev/null +++ b/tests/ui/coherence/orphan-check-projections-nested.rs @@ -0,0 +1,23 @@ +// This used to ICE in an earlier iteration of #117164. Minimized from crate `proqnt`. + +//@ check-pass +//@ revisions: classic next +//@[next] compile-flags: -Znext-solver +//@ aux-crate:dep=trait-with-assoc-ty.rs +//@ edition: 2021 + +pub(crate) trait Trait { + type Assoc; +} + +pub(crate) struct Type(T, U, V); + +impl dep::Trait for Type::Assoc as Trait>::Assoc, U> +where + T: dep::Trait, + ::Assoc: Trait, +{ + type Assoc = U; +} + +fn main() {} diff --git a/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.classic.stderr b/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.classic.stderr new file mode 100644 index 000000000000..d83a56c0bd0e --- /dev/null +++ b/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.classic.stderr @@ -0,0 +1,15 @@ +warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + --> $DIR/orphan-check-projections-not-covering-ambiguity.rs:25:6 + | +LL | impl foreign::Trait1 for ::Output {} + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124559 + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + = note: `#[warn(uncovered_param_in_projection)]` on by default + +warning: 1 warning emitted + +For more information about this error, try `rustc --explain E0210`. diff --git a/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.next.stderr b/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.next.stderr new file mode 100644 index 000000000000..d83a56c0bd0e --- /dev/null +++ b/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.next.stderr @@ -0,0 +1,15 @@ +warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + --> $DIR/orphan-check-projections-not-covering-ambiguity.rs:25:6 + | +LL | impl foreign::Trait1 for ::Output {} + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124559 + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + = note: `#[warn(uncovered_param_in_projection)]` on by default + +warning: 1 warning emitted + +For more information about this error, try `rustc --explain E0210`. diff --git a/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.rs b/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.rs new file mode 100644 index 000000000000..227d8535232d --- /dev/null +++ b/tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.rs @@ -0,0 +1,29 @@ +// This test demonstrates a limitation of the trait solver. +// Basically, one might think that `T` was covered by the projection since the +// latter appears to normalize to a local type. However, since we instantiate the +// constituent types of the self type of impls with fresh infer vars and try to +// normalize them during orphan checking, we wind up trying to normalize a +// projection whose self type is an infer var which unconditionally fails due to +// ambiguity. + +//@ revisions: classic next +//@[next] compile-flags: -Znext-solver + +//@ check-pass +//@ compile-flags: --crate-type=lib +//@ aux-crate:foreign=parametrized-trait.rs +//@ edition:2021 + +trait Project { type Output; } + +impl Project for T { + type Output = Local; +} + +struct Local; + +impl foreign::Trait1 for ::Output {} +//~^ WARNING type parameter `T` must be covered by another type +//~| WARNING this was previously accepted by the compiler + +fn main() {} diff --git a/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.classic.stderr b/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.classic.stderr new file mode 100644 index 000000000000..8964fefedd49 --- /dev/null +++ b/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.classic.stderr @@ -0,0 +1,26 @@ +warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`LocalTy`) + --> $DIR/orphan-check-projections-not-covering-multiple-params.rs:17:6 + | +LL | impl foreign::Trait0 for <() as Trait>::Assoc {} + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`LocalTy`) + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124559 + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + = note: `#[warn(uncovered_param_in_projection)]` on by default + +warning[E0210]: type parameter `U` must be covered by another type when it appears before the first local type (`LocalTy`) + --> $DIR/orphan-check-projections-not-covering-multiple-params.rs:17:9 + | +LL | impl foreign::Trait0 for <() as Trait>::Assoc {} + | ^ type parameter `U` must be covered by another type when it appears before the first local type (`LocalTy`) + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124559 + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + +warning: 2 warnings emitted + +For more information about this error, try `rustc --explain E0210`. diff --git a/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.next.stderr b/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.next.stderr new file mode 100644 index 000000000000..8964fefedd49 --- /dev/null +++ b/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.next.stderr @@ -0,0 +1,26 @@ +warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`LocalTy`) + --> $DIR/orphan-check-projections-not-covering-multiple-params.rs:17:6 + | +LL | impl foreign::Trait0 for <() as Trait>::Assoc {} + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`LocalTy`) + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124559 + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + = note: `#[warn(uncovered_param_in_projection)]` on by default + +warning[E0210]: type parameter `U` must be covered by another type when it appears before the first local type (`LocalTy`) + --> $DIR/orphan-check-projections-not-covering-multiple-params.rs:17:9 + | +LL | impl foreign::Trait0 for <() as Trait>::Assoc {} + | ^ type parameter `U` must be covered by another type when it appears before the first local type (`LocalTy`) + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124559 + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + +warning: 2 warnings emitted + +For more information about this error, try `rustc --explain E0210`. diff --git a/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.rs b/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.rs new file mode 100644 index 000000000000..c5340e854054 --- /dev/null +++ b/tests/ui/coherence/orphan-check-projections-not-covering-multiple-params.rs @@ -0,0 +1,24 @@ +//@ revisions: classic next +//@[next] compile-flags: -Znext-solver + +//@ check-pass +//@ compile-flags: --crate-type=lib +//@ aux-crate:foreign=parametrized-trait.rs +//@ edition:2021 + +trait Trait { type Assoc; } + +impl Trait for () { + type Assoc = LocalTy; +} + +struct LocalTy; + +impl foreign::Trait0 for <() as Trait>::Assoc {} +//~^ WARNING type parameter `T` must be covered by another type +//~| WARNING this was previously accepted by the compiler +//~| WARNING type parameter `U` must be covered by another type +//~| WARNING this was previously accepted by the compiler + + +fn main() {} diff --git a/tests/ui/coherence/orphan-check-projections-not-covering.classic.stderr b/tests/ui/coherence/orphan-check-projections-not-covering.classic.stderr new file mode 100644 index 000000000000..28b8c3f4a94b --- /dev/null +++ b/tests/ui/coherence/orphan-check-projections-not-covering.classic.stderr @@ -0,0 +1,37 @@ +warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + --> $DIR/orphan-check-projections-not-covering.rs:22:6 + | +LL | impl foreign::Trait0 for ::Output {} + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124559 + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + = note: `#[warn(uncovered_param_in_projection)]` on by default + +warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + --> $DIR/orphan-check-projections-not-covering.rs:27:6 + | +LL | impl foreign::Trait0<::Output, Local, T> for Option {} + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124559 + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + +warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + --> $DIR/orphan-check-projections-not-covering.rs:40:6 + | +LL | impl foreign::Trait1 for ::Output {} + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124559 + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + +warning: 3 warnings emitted + +For more information about this error, try `rustc --explain E0210`. diff --git a/tests/ui/coherence/orphan-check-projections-not-covering.next.stderr b/tests/ui/coherence/orphan-check-projections-not-covering.next.stderr new file mode 100644 index 000000000000..28b8c3f4a94b --- /dev/null +++ b/tests/ui/coherence/orphan-check-projections-not-covering.next.stderr @@ -0,0 +1,37 @@ +warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + --> $DIR/orphan-check-projections-not-covering.rs:22:6 + | +LL | impl foreign::Trait0 for ::Output {} + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124559 + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + = note: `#[warn(uncovered_param_in_projection)]` on by default + +warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + --> $DIR/orphan-check-projections-not-covering.rs:27:6 + | +LL | impl foreign::Trait0<::Output, Local, T> for Option {} + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124559 + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + +warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + --> $DIR/orphan-check-projections-not-covering.rs:40:6 + | +LL | impl foreign::Trait1 for ::Output {} + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124559 + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + +warning: 3 warnings emitted + +For more information about this error, try `rustc --explain E0210`. diff --git a/tests/ui/coherence/orphan-check-projections-not-covering.rs b/tests/ui/coherence/orphan-check-projections-not-covering.rs new file mode 100644 index 000000000000..8c2a9a17e2b8 --- /dev/null +++ b/tests/ui/coherence/orphan-check-projections-not-covering.rs @@ -0,0 +1,42 @@ +// Regression test for issue #99554. +// Projections might not cover type parameters. + +//@ revisions: classic next +//@[next] compile-flags: -Znext-solver + +//@ check-pass +//@ compile-flags: --crate-type=lib +//@ aux-crate:foreign=parametrized-trait.rs +//@ edition:2021 + +trait Identity { + type Output; +} + +impl Identity for T { + type Output = T; +} + +struct Local; + +impl foreign::Trait0 for ::Output {} +//~^ WARNING type parameter `T` must be covered by another type +//~| WARNING this was previously accepted by the compiler + + +impl foreign::Trait0<::Output, Local, T> for Option {} +//~^ WARNING type parameter `T` must be covered by another type +//~| WARNING this was previously accepted by the compiler + +pub trait Deferred { + type Output; +} + +// A downstream user could implement +// +// impl Deferred for Type { type Output = T; } +// struct Type(T); +// +impl foreign::Trait1 for ::Output {} +//~^ WARNING type parameter `T` must be covered by another type +//~| WARNING this was previously accepted by the compiler diff --git a/tests/ui/coherence/orphan-check-projections-unsat-bounds.classic.stderr b/tests/ui/coherence/orphan-check-projections-unsat-bounds.classic.stderr new file mode 100644 index 000000000000..0346a9d665cf --- /dev/null +++ b/tests/ui/coherence/orphan-check-projections-unsat-bounds.classic.stderr @@ -0,0 +1,15 @@ +warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`LocalTy`) + --> $DIR/orphan-check-projections-unsat-bounds.rs:28:6 + | +LL | impl foreign::Trait1 for as Discard>::Output + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`LocalTy`) + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124559 + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + = note: `#[warn(uncovered_param_in_projection)]` on by default + +warning: 1 warning emitted + +For more information about this error, try `rustc --explain E0210`. diff --git a/tests/ui/coherence/orphan-check-projections-unsat-bounds.next.stderr b/tests/ui/coherence/orphan-check-projections-unsat-bounds.next.stderr new file mode 100644 index 000000000000..0346a9d665cf --- /dev/null +++ b/tests/ui/coherence/orphan-check-projections-unsat-bounds.next.stderr @@ -0,0 +1,15 @@ +warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`LocalTy`) + --> $DIR/orphan-check-projections-unsat-bounds.rs:28:6 + | +LL | impl foreign::Trait1 for as Discard>::Output + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`LocalTy`) + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #124559 + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + = note: `#[warn(uncovered_param_in_projection)]` on by default + +warning: 1 warning emitted + +For more information about this error, try `rustc --explain E0210`. diff --git a/tests/ui/coherence/orphan-check-projections-unsat-bounds.rs b/tests/ui/coherence/orphan-check-projections-unsat-bounds.rs new file mode 100644 index 000000000000..bc52673a016f --- /dev/null +++ b/tests/ui/coherence/orphan-check-projections-unsat-bounds.rs @@ -0,0 +1,35 @@ +// This used to ICE in an earlier iteration of #117164. +// The normalization performed during orphan checking happens inside an empty ParamEnv and +// with type parameters mapped to fresh infer vars. Therefore it may fail for example due to +// unsatisfied bounds while normalization outside of orphan checking succeeds. + +//@ revisions: classic next +//@[next] compile-flags: -Znext-solver + +//@ check-pass +//@ aux-crate:foreign=parametrized-trait.rs +//@ edition:2021 + +struct Wrapper(T); + +trait Bound {} + +trait Discard { type Output; } + +impl Discard for Wrapper +where + Wrapper: Bound +{ + type Output = LocalTy; +} + +struct LocalTy; + +impl foreign::Trait1 for as Discard>::Output +//~^ WARNING type parameter `T` must be covered by another type +//~| WARNING this was previously accepted by the compiler +where + Wrapper: Bound +{} + +fn main() {} diff --git a/tests/ui/coherence/orphan-check-weak-aliases-covering.rs b/tests/ui/coherence/orphan-check-weak-aliases-covering.rs new file mode 100644 index 000000000000..a8b9e905c70b --- /dev/null +++ b/tests/ui/coherence/orphan-check-weak-aliases-covering.rs @@ -0,0 +1,20 @@ +// Weak aliases cover type parameters if they normalize to a (local) type that covers them. + +//@ check-pass +//@ revisions: classic next +//@[next] compile-flags: -Znext-solver + +//@ aux-crate:foreign=parametrized-trait.rs +//@ edition:2021 + +#![feature(lazy_type_alias)] +#![allow(incomplete_features)] + +type Alias = LocalWrapper; + +struct Local; +struct LocalWrapper(T); + +impl foreign::Trait1 for Alias {} + +fn main() {} diff --git a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.classic.stderr b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.classic.stderr new file mode 100644 index 000000000000..276833fa1712 --- /dev/null +++ b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.classic.stderr @@ -0,0 +1,12 @@ +error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + --> $DIR/orphan-check-weak-aliases-not-covering.rs:16:6 + | +LL | impl foreign::Trait1 for Identity {} + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.next.stderr b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.next.stderr new file mode 100644 index 000000000000..276833fa1712 --- /dev/null +++ b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.next.stderr @@ -0,0 +1,12 @@ +error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + --> $DIR/orphan-check-weak-aliases-not-covering.rs:16:6 + | +LL | impl foreign::Trait1 for Identity {} + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs new file mode 100644 index 000000000000..9ebc45a88293 --- /dev/null +++ b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs @@ -0,0 +1,19 @@ +// Weak aliases might not cover type parameters. + +//@ revisions: classic next +//@[next] compile-flags: -Znext-solver + +//@ aux-crate:foreign=parametrized-trait.rs +//@ edition:2021 + +#![feature(lazy_type_alias)] +#![allow(incomplete_features)] + +type Identity = T; + +struct Local; + +impl foreign::Trait1 for Identity {} +//~^ ERROR type parameter `T` must be covered by another type + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/coherence.stderr b/tests/ui/type-alias-impl-trait/coherence.stderr index 4462b70f782b..266a532a1db1 100644 --- a/tests/ui/type-alias-impl-trait/coherence.stderr +++ b/tests/ui/type-alias-impl-trait/coherence.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl foreign_crate::ForeignTrait for AliasOfForeignType<()> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------- | | | - | | `AliasOfForeignType<()>` is not defined in the current crate + | | type alias impl trait is treated as if it were foreign, because its hidden type could be from a foreign crate | impl doesn't use only types from inside the current crate | = note: define and implement a trait or new type instead From da969d41a31b6838500b626d9699f65459198387 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 30 Apr 2024 20:02:55 +0000 Subject: [PATCH 206/279] fix `NormalizesTo` proof tree issue --- .../src/solve/inspect/analyse.rs | 168 ++++++++++++------ ...ization-overlap-projection.current.stderr} | 2 +- ...cialization-overlap-projection.next.stderr | 49 +++++ .../specialization-overlap-projection.rs | 10 +- 4 files changed, 177 insertions(+), 52 deletions(-) rename tests/ui/specialization/{specialization-overlap-projection.stderr => specialization-overlap-projection.current.stderr} (89%) create mode 100644 tests/ui/specialization/specialization-overlap-projection.next.stderr diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 1c13446213b8..00fe9bc12b5d 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -14,6 +14,7 @@ use rustc_ast_ir::visit::VisitorResult; use rustc_infer::infer::resolve::EagerResolver; use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; +use rustc_infer::traits::{TraitEngine, TraitEngineExt}; use rustc_macros::extension; use rustc_middle::infer::unify_key::ConstVariableOrigin; use rustc_middle::traits::query::NoSolution; @@ -22,9 +23,10 @@ use rustc_middle::traits::solve::{Certainty, Goal}; use rustc_middle::traits::ObligationCause; use rustc_middle::ty; use rustc_middle::ty::TypeFoldable; -use rustc_span::Span; +use rustc_span::{Span, DUMMY_SP}; use crate::solve::eval_ctxt::canonical; +use crate::solve::FulfillmentCtxt; use crate::solve::{EvalCtxt, GoalEvaluationKind, GoalSource}; use crate::solve::{GenerateProofTree, InferCtxtEvalExt}; @@ -37,7 +39,52 @@ pub struct InspectGoal<'a, 'tcx> { depth: usize, orig_values: Vec>, goal: Goal<'tcx, ty::Predicate<'tcx>>, - evaluation: inspect::CanonicalGoalEvaluation<'tcx>, + result: Result, + evaluation_kind: inspect::CanonicalGoalEvaluationKind<'tcx>, + /// The expected term of a `NormalizesTo` goal. It gets + /// replaced with an unconstrained inference variable when + /// computing `NormalizesTo` goals and we return the nested + /// goals to the caller, who also equates the actual term + /// with the expected. + /// + /// This is an implementation detail of the trait solver and + /// not something we want to leak to users. We therefore + /// treat `NormalizesTo` goals as if they apply the expected + /// type at the end of each candidate. + normalizes_to_term_hack: Option>, +} + +#[derive(Copy, Clone)] +struct NormalizesToTermHack<'tcx> { + term: ty::Term<'tcx>, + unconstrained_term: ty::Term<'tcx>, +} + +impl<'tcx> NormalizesToTermHack<'tcx> { + fn relate( + self, + infcx: &InferCtxt<'tcx>, + span: Span, + param_env: ty::ParamEnv<'tcx>, + ) -> Result { + infcx + .at(&ObligationCause::dummy_with_span(span), param_env) + .eq(DefineOpaqueTypes::Yes, self.term, self.unconstrained_term) + .map_err(|_| NoSolution) + .and_then(|InferOk { value: (), obligations }| { + let mut fulfill_cx = FulfillmentCtxt::new(infcx); + fulfill_cx.register_predicate_obligations(infcx, obligations); + if fulfill_cx.select_where_possible(infcx).is_empty() { + if fulfill_cx.pending_obligations().is_empty() { + Ok(Certainty::Yes) + } else { + Ok(Certainty::AMBIGUOUS) + } + } else { + Err(NoSolution) + } + }) + } } pub struct InspectCandidate<'a, 'tcx> { @@ -115,42 +162,47 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { self.final_state, ); + if let Some(term_hack) = self.goal.normalizes_to_term_hack { + // FIXME: We ignore the expected term of `NormalizesTo` goals + // when computing the result of its candidates. This is + // scuffed. + let _ = term_hack.relate(infcx, span, param_env); + } + instantiated_goals .into_iter() - .map(|goal| { - let proof_tree = match goal.predicate.kind().no_bound_vars() { - Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => { - let unconstrained_term = match term.unpack() { - ty::TermKind::Ty(_) => infcx - .next_ty_var(TypeVariableOrigin { param_def_id: None, span }) - .into(), - ty::TermKind::Const(ct) => infcx - .next_const_var( - ct.ty(), - ConstVariableOrigin { param_def_id: None, span }, - ) - .into(), - }; - let goal = goal - .with(infcx.tcx, ty::NormalizesTo { alias, term: unconstrained_term }); - let proof_tree = - EvalCtxt::enter_root(infcx, GenerateProofTree::Yes, |ecx| { - ecx.evaluate_goal_raw( - GoalEvaluationKind::Root, - GoalSource::Misc, - goal, - ) - }) - .1; - let InferOk { value: (), obligations: _ } = infcx - .at(&ObligationCause::dummy_with_span(span), param_env) - .eq(DefineOpaqueTypes::Yes, term, unconstrained_term) - .unwrap(); - proof_tree - } - _ => infcx.evaluate_root_goal(goal, GenerateProofTree::Yes).1, - }; - InspectGoal::new(infcx, self.goal.depth + 1, proof_tree.unwrap()) + .map(|goal| match goal.predicate.kind().no_bound_vars() { + Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => { + let unconstrained_term = match term.unpack() { + ty::TermKind::Ty(_) => infcx + .next_ty_var(TypeVariableOrigin { param_def_id: None, span }) + .into(), + ty::TermKind::Const(ct) => infcx + .next_const_var( + ct.ty(), + ConstVariableOrigin { param_def_id: None, span }, + ) + .into(), + }; + let goal = + goal.with(infcx.tcx, ty::NormalizesTo { alias, term: unconstrained_term }); + let proof_tree = EvalCtxt::enter_root(infcx, GenerateProofTree::Yes, |ecx| { + ecx.evaluate_goal_raw(GoalEvaluationKind::Root, GoalSource::Misc, goal) + }) + .1; + InspectGoal::new( + infcx, + self.goal.depth + 1, + proof_tree.unwrap(), + Some(NormalizesToTermHack { term, unconstrained_term }), + ) + } + _ => InspectGoal::new( + infcx, + self.goal.depth + 1, + infcx.evaluate_root_goal(goal, GenerateProofTree::Yes).1.unwrap(), + None, + ), }) .collect() } @@ -172,7 +224,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { } pub fn result(&self) -> Result { - self.evaluation.result.map(|c| c.value.certainty) + self.result } fn candidates_recur( @@ -229,11 +281,11 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { pub fn candidates(&'a self) -> Vec> { let mut candidates = vec![]; - let last_eval_step = match self.evaluation.kind { + let last_eval_step = match self.evaluation_kind { inspect::CanonicalGoalEvaluationKind::Overflow | inspect::CanonicalGoalEvaluationKind::CycleInStack | inspect::CanonicalGoalEvaluationKind::ProvisionalCacheHit => { - warn!("unexpected root evaluation: {:?}", self.evaluation); + warn!("unexpected root evaluation: {:?}", self.evaluation_kind); return vec![]; } inspect::CanonicalGoalEvaluationKind::Evaluation { revisions } => { @@ -262,17 +314,33 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { candidates.pop().filter(|_| candidates.is_empty()) } - fn new(infcx: &'a InferCtxt<'tcx>, depth: usize, root: inspect::GoalEvaluation<'tcx>) -> Self { + fn new( + infcx: &'a InferCtxt<'tcx>, + depth: usize, + root: inspect::GoalEvaluation<'tcx>, + normalizes_to_term_hack: Option>, + ) -> Self { let inspect::GoalEvaluation { uncanonicalized_goal, kind, evaluation } = root; - match kind { - inspect::GoalEvaluationKind::Root { orig_values } => InspectGoal { - infcx, - depth, - orig_values, - goal: uncanonicalized_goal.fold_with(&mut EagerResolver::new(infcx)), - evaluation, - }, - inspect::GoalEvaluationKind::Nested { .. } => unreachable!(), + let inspect::GoalEvaluationKind::Root { orig_values } = kind else { unreachable!() }; + + let result = evaluation.result.and_then(|ok| { + if let Some(term_hack) = normalizes_to_term_hack { + infcx + .probe(|_| term_hack.relate(infcx, DUMMY_SP, uncanonicalized_goal.param_env)) + .map(|certainty| ok.value.certainty.unify_with(certainty)) + } else { + Ok(ok.value.certainty) + } + }); + + InspectGoal { + infcx, + depth, + orig_values, + goal: uncanonicalized_goal.fold_with(&mut EagerResolver::new(infcx)), + result, + evaluation_kind: evaluation.kind, + normalizes_to_term_hack, } } } @@ -299,6 +367,6 @@ impl<'tcx> InferCtxt<'tcx> { ) -> V::Result { let (_, proof_tree) = self.evaluate_root_goal(goal, GenerateProofTree::Yes); let proof_tree = proof_tree.unwrap(); - visitor.visit_goal(&InspectGoal::new(self, 0, proof_tree)) + visitor.visit_goal(&InspectGoal::new(self, 0, proof_tree, None)) } } diff --git a/tests/ui/specialization/specialization-overlap-projection.stderr b/tests/ui/specialization/specialization-overlap-projection.current.stderr similarity index 89% rename from tests/ui/specialization/specialization-overlap-projection.stderr rename to tests/ui/specialization/specialization-overlap-projection.current.stderr index 708c0817fd96..a69826fa96b0 100644 --- a/tests/ui/specialization/specialization-overlap-projection.stderr +++ b/tests/ui/specialization/specialization-overlap-projection.current.stderr @@ -1,5 +1,5 @@ warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-overlap-projection.rs:7:12 + --> $DIR/specialization-overlap-projection.rs:10:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ diff --git a/tests/ui/specialization/specialization-overlap-projection.next.stderr b/tests/ui/specialization/specialization-overlap-projection.next.stderr new file mode 100644 index 000000000000..ab040193fa4c --- /dev/null +++ b/tests/ui/specialization/specialization-overlap-projection.next.stderr @@ -0,0 +1,49 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/specialization-overlap-projection.rs:10:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +error[E0119]: conflicting implementations of trait `Foo` for type `u32` + --> $DIR/specialization-overlap-projection.rs:28:1 + | +LL | impl Foo for u32 {} + | ---------------- first implementation here +LL | impl Foo for ::Output {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` + +error[E0119]: conflicting implementations of trait `Foo` for type `u32` + --> $DIR/specialization-overlap-projection.rs:30:1 + | +LL | impl Foo for u32 {} + | ---------------- first implementation here +... +LL | impl Foo for ::Output {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` + +error[E0282]: type annotations needed + --> $DIR/specialization-overlap-projection.rs:17:27 + | +LL | default type Output = bool; + | ^^^^ cannot infer type for associated type `::Output` + +error[E0282]: type annotations needed + --> $DIR/specialization-overlap-projection.rs:21:35 + | +LL | impl Assoc for u8 { type Output = u8; } + | ^^ cannot infer type for associated type `::Output` + +error[E0282]: type annotations needed + --> $DIR/specialization-overlap-projection.rs:23:36 + | +LL | impl Assoc for u16 { type Output = u16; } + | ^^^ cannot infer type for associated type `::Output` + +error: aborting due to 5 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0119, E0282. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/specialization-overlap-projection.rs b/tests/ui/specialization/specialization-overlap-projection.rs index 66951b9d50c6..78e75f623c4b 100644 --- a/tests/ui/specialization/specialization-overlap-projection.rs +++ b/tests/ui/specialization/specialization-overlap-projection.rs @@ -1,4 +1,7 @@ -//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[current] check-pass // Test that impls on projected self types can resolve overlap, even when the // projections involve specialization, so long as the associated type is @@ -12,14 +15,19 @@ trait Assoc { impl Assoc for T { default type Output = bool; + //[next]~^ ERROR type annotations needed } impl Assoc for u8 { type Output = u8; } +//[next]~^ ERROR type annotations needed impl Assoc for u16 { type Output = u16; } +//[next]~^ ERROR type annotations needed trait Foo {} impl Foo for u32 {} impl Foo for ::Output {} +//[next]~^ ERROR conflicting implementations of trait `Foo` for type `u32` impl Foo for ::Output {} +//[next]~^ ERROR conflicting implementations of trait `Foo` for type `u32` fn main() {} From 9e739b723b822e7f11508f516370da5b298cab17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Thu, 25 Apr 2024 01:58:41 +0200 Subject: [PATCH 207/279] Give items related to issue 33140 a more meaningful name --- compiler/rustc_middle/src/query/mod.rs | 6 ++- compiler/rustc_middle/src/ty/mod.rs | 45 +++++++++---------- .../src/traits/select/mod.rs | 2 +- .../src/traits/specialize/mod.rs | 4 +- .../traits/specialize/specialization_graph.rs | 6 +-- compiler/rustc_ty_utils/src/ty.rs | 32 ++++++------- 6 files changed, 49 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f689a73d4bc2..c2f7a227f666 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -847,8 +847,10 @@ rustc_queries! { separate_provide_extern } - query issue33140_self_ty(key: DefId) -> Option>> { - desc { |tcx| "computing Self type wrt issue #33140 `{}`", tcx.def_path_str(key) } + query self_ty_of_trait_impl_enabling_order_dep_trait_object_hack( + key: DefId + ) -> Option>> { + desc { |tcx| "computing self type wrt issue #33140 `{}`", tcx.def_path_str(key) } } /// Maps a `DefId` of a type to a list of its inherent impls. diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f6146cfe5165..73b20f0485b6 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1503,14 +1503,14 @@ pub enum ImplOverlapKind { /// Whether or not the impl is permitted due to the trait being a `#[marker]` trait marker: bool, }, - /// These impls are allowed to overlap, but that raises - /// an issue #33140 future-compatibility warning. + /// These impls are allowed to overlap, but that raises an + /// issue #33140 future-compatibility warning (tracked in #56484). /// /// Some background: in Rust 1.0, the trait-object types `Send + Sync` (today's /// `dyn Send + Sync`) and `Sync + Send` (now `dyn Sync + Send`) were different. /// - /// The widely-used version 0.1.0 of the crate `traitobject` had accidentally relied - /// that difference, making what reduces to the following set of impls: + /// The widely-used version 0.1.0 of the crate `traitobject` had accidentally relied on + /// that difference, doing what reduces to the following set of impls: /// /// ```compile_fail,(E0119) /// trait Trait {} @@ -1535,7 +1535,7 @@ pub enum ImplOverlapKind { /// 4. Neither of the impls can have any where-clauses. /// /// Once `traitobject` 0.1.0 is no longer an active concern, this hack can be removed. - Issue33140, + FutureCompatOrderDepTraitObjects, } /// Useful source information about where a desugared associated type for an @@ -1730,27 +1730,26 @@ impl<'tcx> TyCtxt<'tcx> { | (ImplPolarity::Negative, ImplPolarity::Negative) => {} }; - let is_marker_overlap = { - let is_marker_impl = - |trait_ref: TraitRef<'_>| -> bool { self.trait_def(trait_ref.def_id).is_marker }; - is_marker_impl(trait_ref1) && is_marker_impl(trait_ref2) - }; + let is_marker_impl = |trait_ref: TraitRef<'_>| self.trait_def(trait_ref.def_id).is_marker; + let is_marker_overlap = is_marker_impl(trait_ref1) && is_marker_impl(trait_ref2); if is_marker_overlap { - Some(ImplOverlapKind::Permitted { marker: true }) - } else { - if let Some(self_ty1) = self.issue33140_self_ty(def_id1) { - if let Some(self_ty2) = self.issue33140_self_ty(def_id2) { - if self_ty1 == self_ty2 { - return Some(ImplOverlapKind::Issue33140); - } else { - debug!("found {self_ty1:?} != {self_ty2:?}"); - } - } - } - - None + return Some(ImplOverlapKind::Permitted { marker: true }); } + + if let Some(self_ty1) = + self.self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(def_id1) + && let Some(self_ty2) = + self.self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(def_id2) + { + if self_ty1 == self_ty2 { + return Some(ImplOverlapKind::FutureCompatOrderDepTraitObjects); + } else { + debug!("found {self_ty1:?} != {self_ty2:?}"); + } + } + + None } /// Returns `ty::VariantDef` if `res` refers to a struct, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index fc12fed35373..35ab333c9b31 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2001,7 +2001,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // any associated items and there are no where-clauses. // // We can just arbitrarily drop one of the impls. - Some(ty::ImplOverlapKind::Issue33140) => { + Some(ty::ImplOverlapKind::FutureCompatOrderDepTraitObjects) => { assert_eq!(other.evaluation, victim.evaluation); DropVictim::Yes } diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 46a0a4eb5ef8..390e711a18d9 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -453,7 +453,7 @@ fn report_conflicting_impls<'tcx>( overlap.trait_ref.print_trait_sugared(), overlap.self_ty.map_or_else(String::new, |ty| format!(" for type `{ty}`")), match used_to_be_allowed { - Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)", + Some(FutureCompatOverlapErrorKind::OrderDepTraitObjects) => ": (E0119)", _ => "", } ) @@ -480,7 +480,7 @@ fn report_conflicting_impls<'tcx>( } Some(kind) => { let lint = match kind { - FutureCompatOverlapErrorKind::Issue33140 => ORDER_DEPENDENT_TRAIT_OBJECTS, + FutureCompatOverlapErrorKind::OrderDepTraitObjects => ORDER_DEPENDENT_TRAIT_OBJECTS, FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK, }; tcx.node_span_lint( diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs index 681f84f20428..b6c2fcb46eb8 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs @@ -11,7 +11,7 @@ pub use rustc_middle::traits::specialization_graph::*; #[derive(Copy, Clone, Debug)] pub enum FutureCompatOverlapErrorKind { - Issue33140, + OrderDepTraitObjects, LeakCheck, } @@ -150,10 +150,10 @@ impl<'tcx> Children { { match overlap_kind { ty::ImplOverlapKind::Permitted { marker: _ } => {} - ty::ImplOverlapKind::Issue33140 => { + ty::ImplOverlapKind::FutureCompatOrderDepTraitObjects => { *last_lint_mut = Some(FutureCompatOverlapError { error: create_overlap_error(overlap), - kind: FutureCompatOverlapErrorKind::Issue33140, + kind: FutureCompatOverlapErrorKind::OrderDepTraitObjects, }); } } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 2139b8c665bf..fa1085c7cd79 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -243,37 +243,39 @@ fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamE tcx.param_env(def_id).with_reveal_all_normalized(tcx) } -/// If `def_id` is an issue 33140 hack impl, returns its self type; otherwise, returns `None`. +/// If the given trait impl enables exploiting the former order dependence of trait objects, +/// returns its self type; otherwise, returns `None`. /// -/// See [`ty::ImplOverlapKind::Issue33140`] for more details. -fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option>> { - debug!("issue33140_self_ty({:?})", def_id); - - let impl_ = tcx - .impl_trait_header(def_id) - .unwrap_or_else(|| bug!("issue33140_self_ty called on inherent impl {:?}", def_id)); +/// See [`ty::ImplOverlapKind::FutureCompatOrderDepTraitObjects`] for more details. +#[instrument(level = "debug", skip(tcx))] +fn self_ty_of_trait_impl_enabling_order_dep_trait_object_hack( + tcx: TyCtxt<'_>, + def_id: DefId, +) -> Option>> { + let impl_ = + tcx.impl_trait_header(def_id).unwrap_or_else(|| bug!("called on inherent impl {def_id:?}")); let trait_ref = impl_.trait_ref.skip_binder(); - debug!("issue33140_self_ty({:?}), trait-ref={:?}", def_id, trait_ref); + debug!(?trait_ref); let is_marker_like = impl_.polarity == ty::ImplPolarity::Positive && tcx.associated_item_def_ids(trait_ref.def_id).is_empty(); // Check whether these impls would be ok for a marker trait. if !is_marker_like { - debug!("issue33140_self_ty - not marker-like!"); + debug!("not marker-like!"); return None; } // impl must be `impl Trait for dyn Marker1 + Marker2 + ...` if trait_ref.args.len() != 1 { - debug!("issue33140_self_ty - impl has args!"); + debug!("impl has args!"); return None; } let predicates = tcx.predicates_of(def_id); if predicates.parent.is_some() || !predicates.predicates.is_empty() { - debug!("issue33140_self_ty - impl has predicates {:?}!", predicates); + debug!(?predicates, "impl has predicates!"); return None; } @@ -284,10 +286,10 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option Date: Thu, 25 Apr 2024 02:03:51 +0200 Subject: [PATCH 208/279] Give an item related to issue 27438 a more meaningful name --- compiler/rustc_data_structures/src/lib.rs | 4 ++-- compiler/rustc_middle/src/tests.rs | 14 ++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 495c1977df9d..0c322939db97 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -144,9 +144,9 @@ pub fn make_display(f: impl Fn(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl Printer { f } } -// See comments in compiler/rustc_middle/src/tests.rs +// See comment in compiler/rustc_middle/src/tests.rs and issue #27438. #[doc(hidden)] -pub fn __noop_fix_for_27438() {} +pub fn __noop_fix_for_windows_dllimport_issue() {} #[macro_export] macro_rules! external_bitflags_debug { diff --git a/compiler/rustc_middle/src/tests.rs b/compiler/rustc_middle/src/tests.rs index 0af75e6ff6c3..6c2e5f63418a 100644 --- a/compiler/rustc_middle/src/tests.rs +++ b/compiler/rustc_middle/src/tests.rs @@ -1,11 +1,9 @@ -// FIXME(#27438): right now the unit tests of rustc_middle don't refer to any actual -// functions generated in rustc_data_structures (all -// references are through generic functions), but statics are -// referenced from time to time. Due to this bug we won't -// actually correctly link in the statics unless we also -// reference a function, so be sure to reference a dummy -// function. +// FIXME(#27438): Right now, the unit tests of `rustc_middle` don't refer to any actual functions +// generated in `rustc_data_structures` (all references are through generic functions), +// but statics are referenced from time to time. Due to this Windows `dllimport` bug +// we won't actually correctly link in the statics unless we also reference a function, +// so be sure to reference a dummy function. #[test] fn noop() { - rustc_data_structures::__noop_fix_for_27438(); + rustc_data_structures::__noop_fix_for_windows_dllimport_issue(); } From 2a1d748254d3241967cf7d2bad141a371ccc7c99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Thu, 25 Apr 2024 03:11:19 +0200 Subject: [PATCH 209/279] Replace item names containing an error code with something more meaningful or inline such functions if useless. --- .../rustc_ast_passes/src/ast_validation.rs | 11 +++++------ compiler/rustc_hir_analysis/messages.ftl | 6 ++++++ .../rustc_hir_analysis/src/check/wfcheck.rs | 18 ++++-------------- compiler/rustc_hir_analysis/src/errors.rs | 10 ++++++++++ compiler/rustc_hir_typeck/src/pat.rs | 14 ++++++++++---- .../src/thir/pattern/check_match.rs | 16 +++++----------- .../async-await/inference_var_self_argument.rs | 2 +- .../inference_var_self_argument.stderr | 2 +- tests/ui/async-await/issue-66312.stderr | 2 +- .../feature-gate-dispatch-from-dyn-cell.rs | 2 +- .../feature-gate-dispatch-from-dyn-cell.stderr | 2 +- tests/ui/issues/issue-56806.stderr | 2 +- tests/ui/self/arbitrary-self-opaque.rs | 2 +- tests/ui/self/arbitrary-self-opaque.stderr | 2 +- tests/ui/span/issue-27522.stderr | 2 +- ...-unsafe-trait-should-use-where-sized.stderr | 2 +- tests/ui/traits/issue-78372.rs | 2 +- tests/ui/traits/issue-78372.stderr | 2 +- tests/ui/ufcs/ufcs-explicit-self-bad.stderr | 6 +++--- 19 files changed, 55 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 1eefad2af4dc..172e97e72717 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -632,20 +632,19 @@ impl<'a> AstValidator<'a> { } } - fn emit_e0568(&self, span: Span, ident: Span) { - self.dcx().emit_err(errors::AutoTraitBounds { span, ident }); - } - fn deny_super_traits(&self, bounds: &GenericBounds, ident_span: Span) { if let [.., last] = &bounds[..] { let span = ident_span.shrink_to_hi().to(last.span()); - self.emit_e0568(span, ident_span); + self.dcx().emit_err(errors::AutoTraitBounds { span, ident: ident_span }); } } fn deny_where_clause(&self, where_clause: &WhereClause, ident_span: Span) { if !where_clause.predicates.is_empty() { - self.emit_e0568(where_clause.span, ident_span); + // FIXME: The current diagnostic is misleading since it only talks about + // super trait and lifetime bounds while we should just say “bounds”. + self.dcx() + .emit_err(errors::AutoTraitBounds { span: where_clause.span, ident: ident_span }); } } diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 06b5ee299b85..2143caf2dee0 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -201,6 +201,12 @@ hir_analysis_inherent_ty_outside_relevant = cannot define inherent `impl` for a .help = consider moving this inherent impl into the crate defining the type if possible .span_help = alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items +hir_analysis_invalid_receiver_ty = invalid `self` parameter type: `{$receiver_ty}` + .note = type of `self` must be `Self` or a type that dereferences to it + +hir_analysis_invalid_receiver_ty_help = + consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + hir_analysis_invalid_union_field = field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union .note = union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>` diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index c26f982fa473..5b127e0bf496 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -2,6 +2,7 @@ use crate::autoderef::Autoderef; use crate::collect::CollectItemTypesVisitor; use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter}; use crate::errors; +use crate::fluent_generated as fluent; use hir::intravisit::Visitor; use rustc_ast as ast; @@ -1636,10 +1637,6 @@ fn check_fn_or_method<'tcx>( } } -const HELP_FOR_SELF_TYPE: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box`, \ - `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one \ - of the previous types except `Self`)"; - #[instrument(level = "debug", skip(wfcx))] fn check_method_receiver<'tcx>( wfcx: &WfCheckingCtxt<'_, 'tcx>, @@ -1675,7 +1672,7 @@ fn check_method_receiver<'tcx>( if tcx.features().arbitrary_self_types { if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) { // Report error; `arbitrary_self_types` was enabled. - return Err(e0307(tcx, span, receiver_ty)); + return Err(tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty })); } } else { if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, false) { @@ -1690,24 +1687,17 @@ fn check_method_receiver<'tcx>( the `arbitrary_self_types` feature", ), ) - .with_help(HELP_FOR_SELF_TYPE) + .with_help(fluent::hir_analysis_invalid_receiver_ty_help) .emit() } else { // Report error; would not have worked with `arbitrary_self_types`. - e0307(tcx, span, receiver_ty) + tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty }) }); } } Ok(()) } -fn e0307(tcx: TyCtxt<'_>, span: Span, receiver_ty: Ty<'_>) -> ErrorGuaranteed { - struct_span_code_err!(tcx.dcx(), span, E0307, "invalid `self` parameter type: {receiver_ty}") - .with_note("type of `self` must be `Self` or a type that dereferences to it") - .with_help(HELP_FOR_SELF_TYPE) - .emit() -} - /// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If /// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly /// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 867ee772a30a..cc8f1495e3c1 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1641,3 +1641,13 @@ pub struct NonConstRange { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_invalid_receiver_ty, code = E0307)] +#[note] +#[help(hir_analysis_invalid_receiver_ty_help)] +pub struct InvalidReceiverTy<'tcx> { + #[primary_span] + pub span: Span, + pub receiver_ty: Ty<'tcx>, +} diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 6040b689f49d..382dba5f95fb 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1228,16 +1228,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } } else { - // Pattern has wrong number of fields. - let e = - self.e0023(pat.span, res, qpath, subpats, &variant.fields.raw, expected, had_err); + let e = self.emit_err_pat_wrong_number_of_fields( + pat.span, + res, + qpath, + subpats, + &variant.fields.raw, + expected, + had_err, + ); on_error(e); return Ty::new_error(tcx, e); } pat_ty } - fn e0023( + fn emit_err_pat_wrong_number_of_fields( &self, pat_span: Span, res: Res, diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 241d38f90d29..25ab90467061 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -10,9 +10,7 @@ use rustc_arena::{DroplessArena, TypedArena}; use rustc_ast::Mutability; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_errors::{ - codes::*, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, MultiSpan, -}; +use rustc_errors::{codes::*, struct_span_code_err, Applicability, ErrorGuaranteed, MultiSpan}; use rustc_hir::def::*; use rustc_hir::def_id::LocalDefId; use rustc_hir::{self as hir, BindingMode, ByRef, HirId}; @@ -24,7 +22,6 @@ use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; use rustc_session::lint::builtin::{ BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS, }; -use rustc_session::Session; use rustc_span::hygiene::DesugaringKind; use rustc_span::{sym, Span}; @@ -64,10 +61,6 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), Err visitor.error } -fn create_e0004(sess: &Session, sp: Span, error_message: String) -> Diag<'_> { - struct_span_code_err!(sess.dcx(), sp, E0004, "{}", &error_message) -} - #[derive(Debug, Copy, Clone, PartialEq)] enum RefutableFlag { Irrefutable, @@ -975,10 +968,11 @@ fn report_non_exhaustive_match<'p, 'tcx>( // FIXME: migration of this diagnostic will require list support let joined_patterns = joined_uncovered_patterns(cx, &witnesses); - let mut err = create_e0004( - cx.tcx.sess, + let mut err = struct_span_code_err!( + cx.tcx.dcx(), sp, - format!("non-exhaustive patterns: {joined_patterns} not covered"), + E0004, + "non-exhaustive patterns: {joined_patterns} not covered" ); err.span_label( sp, diff --git a/tests/ui/async-await/inference_var_self_argument.rs b/tests/ui/async-await/inference_var_self_argument.rs index f4bb8884b058..4d5ac4abb199 100644 --- a/tests/ui/async-await/inference_var_self_argument.rs +++ b/tests/ui/async-await/inference_var_self_argument.rs @@ -4,7 +4,7 @@ trait Foo { async fn foo(self: &dyn Foo) { //~^ ERROR: `Foo` cannot be made into an object - //~| ERROR invalid `self` parameter type: &dyn Foo + //~| ERROR invalid `self` parameter type: `&dyn Foo` todo!() } } diff --git a/tests/ui/async-await/inference_var_self_argument.stderr b/tests/ui/async-await/inference_var_self_argument.stderr index 8a8c1ea03f14..f94ae2a27c33 100644 --- a/tests/ui/async-await/inference_var_self_argument.stderr +++ b/tests/ui/async-await/inference_var_self_argument.stderr @@ -13,7 +13,7 @@ LL | async fn foo(self: &dyn Foo) { | ^^^ ...because method `foo` is `async` = help: consider moving `foo` to another trait -error[E0307]: invalid `self` parameter type: &dyn Foo +error[E0307]: invalid `self` parameter type: `&dyn Foo` --> $DIR/inference_var_self_argument.rs:5:24 | LL | async fn foo(self: &dyn Foo) { diff --git a/tests/ui/async-await/issue-66312.stderr b/tests/ui/async-await/issue-66312.stderr index 2875af8a97e0..702e0b375e57 100644 --- a/tests/ui/async-await/issue-66312.stderr +++ b/tests/ui/async-await/issue-66312.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | if x.is_some() { | ^^^^^^^^^^^ expected `bool`, found `()` -error[E0307]: invalid `self` parameter type: T +error[E0307]: invalid `self` parameter type: `T` --> $DIR/issue-66312.rs:4:22 | LL | fn is_some(self: T); diff --git a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.rs b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.rs index 83366ea02b09..eea6a21ce274 100644 --- a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.rs +++ b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.rs @@ -3,7 +3,7 @@ use std::cell::Cell; trait Trait{ - fn cell(self: Cell<&Self>); //~ ERROR invalid `self` parameter type: Cell<&Self> + fn cell(self: Cell<&Self>); //~ ERROR invalid `self` parameter type: `Cell<&Self>` } fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr index e727b69ffceb..2150effc3b74 100644 --- a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr +++ b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr @@ -1,4 +1,4 @@ -error[E0307]: invalid `self` parameter type: Cell<&Self> +error[E0307]: invalid `self` parameter type: `Cell<&Self>` --> $DIR/feature-gate-dispatch-from-dyn-cell.rs:6:19 | LL | fn cell(self: Cell<&Self>); diff --git a/tests/ui/issues/issue-56806.stderr b/tests/ui/issues/issue-56806.stderr index f3d4c2fef94e..ec50d863758d 100644 --- a/tests/ui/issues/issue-56806.stderr +++ b/tests/ui/issues/issue-56806.stderr @@ -1,4 +1,4 @@ -error[E0307]: invalid `self` parameter type: Box<(dyn Trait + 'static)> +error[E0307]: invalid `self` parameter type: `Box<(dyn Trait + 'static)>` --> $DIR/issue-56806.rs:2:34 | LL | fn dyn_instead_of_self(self: Box); diff --git a/tests/ui/self/arbitrary-self-opaque.rs b/tests/ui/self/arbitrary-self-opaque.rs index 99357dde3e14..3331b037b051 100644 --- a/tests/ui/self/arbitrary-self-opaque.rs +++ b/tests/ui/self/arbitrary-self-opaque.rs @@ -6,7 +6,7 @@ type Bar = impl Sized; impl Foo { fn foo(self: Bar) {} - //~^ ERROR: invalid `self` parameter type: Bar + //~^ ERROR: invalid `self` parameter type: `Bar` } fn main() {} diff --git a/tests/ui/self/arbitrary-self-opaque.stderr b/tests/ui/self/arbitrary-self-opaque.stderr index 6b5db8d84932..0cbe22afac31 100644 --- a/tests/ui/self/arbitrary-self-opaque.stderr +++ b/tests/ui/self/arbitrary-self-opaque.stderr @@ -6,7 +6,7 @@ LL | type Bar = impl Sized; | = note: `Bar` must be used in combination with a concrete type within the same module -error[E0307]: invalid `self` parameter type: Bar +error[E0307]: invalid `self` parameter type: `Bar` --> $DIR/arbitrary-self-opaque.rs:8:18 | LL | fn foo(self: Bar) {} diff --git a/tests/ui/span/issue-27522.stderr b/tests/ui/span/issue-27522.stderr index c2de1562841c..c57a100bbe22 100644 --- a/tests/ui/span/issue-27522.stderr +++ b/tests/ui/span/issue-27522.stderr @@ -1,4 +1,4 @@ -error[E0307]: invalid `self` parameter type: &SomeType +error[E0307]: invalid `self` parameter type: `&SomeType` --> $DIR/issue-27522.rs:6:22 | LL | fn handler(self: &SomeType); diff --git a/tests/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr b/tests/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr index c0dc71df06e6..abbf56cfac86 100644 --- a/tests/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr +++ b/tests/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr @@ -26,7 +26,7 @@ help: consider changing method `bar`'s `self` parameter to be `&self` LL | fn bar(self: &Self) {} | ~~~~~ -error[E0307]: invalid `self` parameter type: () +error[E0307]: invalid `self` parameter type: `()` --> $DIR/object-unsafe-trait-should-use-where-sized.rs:6:18 | LL | fn bar(self: ()) {} diff --git a/tests/ui/traits/issue-78372.rs b/tests/ui/traits/issue-78372.rs index 143325c097c1..b97835bbc57f 100644 --- a/tests/ui/traits/issue-78372.rs +++ b/tests/ui/traits/issue-78372.rs @@ -6,7 +6,7 @@ impl DispatchFromDyn> for T {} //~ ERROR cannot find type `U` //~| ERROR the trait `DispatchFromDyn` may only be implemented for a coercion between structures trait Foo: X {} trait X { - fn foo(self: Smaht); //~ ERROR: invalid `self` + fn foo(self: Smaht); //~ ERROR: invalid `self` parameter type } trait Marker {} impl Marker for dyn Foo {} diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr index edb07957c445..58a4c229e5e6 100644 --- a/tests/ui/traits/issue-78372.stderr +++ b/tests/ui/traits/issue-78372.stderr @@ -79,7 +79,7 @@ LL | trait X { LL | fn foo(self: Smaht); | ^^^^^^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on -error[E0307]: invalid `self` parameter type: Smaht +error[E0307]: invalid `self` parameter type: `Smaht` --> $DIR/issue-78372.rs:9:18 | LL | fn foo(self: Smaht); diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr index 7c2507754751..c48d094daea2 100644 --- a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr +++ b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr @@ -15,7 +15,7 @@ LL | fn dummy2(&self); = note: expected signature `fn(&&'a Bar<_>)` found signature `fn(&Bar<_>)` -error[E0307]: invalid `self` parameter type: isize +error[E0307]: invalid `self` parameter type: `isize` --> $DIR/ufcs-explicit-self-bad.rs:8:18 | LL | fn foo(self: isize, x: isize) -> isize { @@ -24,7 +24,7 @@ LL | fn foo(self: isize, x: isize) -> isize { = note: type of `self` must be `Self` or a type that dereferences to it = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) -error[E0307]: invalid `self` parameter type: Bar +error[E0307]: invalid `self` parameter type: `Bar` --> $DIR/ufcs-explicit-self-bad.rs:19:18 | LL | fn foo(self: Bar, x: isize) -> isize { @@ -33,7 +33,7 @@ LL | fn foo(self: Bar, x: isize) -> isize { = note: type of `self` must be `Self` or a type that dereferences to it = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) -error[E0307]: invalid `self` parameter type: &Bar +error[E0307]: invalid `self` parameter type: `&Bar` --> $DIR/ufcs-explicit-self-bad.rs:23:18 | LL | fn bar(self: &Bar, x: isize) -> isize { From a3ef100fa6fdb7d07c52b35d2462fa74cbf7ccd3 Mon Sep 17 00:00:00 2001 From: bendn Date: Wed, 1 May 2024 07:45:15 +0700 Subject: [PATCH 210/279] warning --- clippy_lints/src/needless_for_each.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/clippy_lints/src/needless_for_each.rs b/clippy_lints/src/needless_for_each.rs index 3fe3d50197d2..630018238f4c 100644 --- a/clippy_lints/src/needless_for_each.rs +++ b/clippy_lints/src/needless_for_each.rs @@ -35,6 +35,16 @@ declare_clippy_lint! { /// println!("{}", elem); /// } /// ``` + /// + /// ### Known Problems + /// When doing things such as: + /// ```ignore + /// let v = vec![0, 1, 2]; + /// v.iter().for_each(|elem| unsafe { + /// libc::printf(c"%d\n".as_ptr(), elem); + /// }); + /// ``` + /// This lint will not trigger. #[clippy::version = "1.53.0"] pub NEEDLESS_FOR_EACH, pedantic, From 9cb8fa81048b939ad5b0205cef48f81a45e86f83 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 30 Apr 2024 22:14:12 -0400 Subject: [PATCH 211/279] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index b60a15551551..6087566b3fa7 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit b60a1555155111e962018007a6d0ef85207db463 +Subproject commit 6087566b3fa73bfda29702632493e938b12d19e5 From fed9940e57949b4e2153a465d22a51a2bc975b6d Mon Sep 17 00:00:00 2001 From: "Christopher B. Speir" Date: Tue, 30 Apr 2024 20:02:32 -0500 Subject: [PATCH 212/279] Remove clippy_utils::paths::VEC_RESIZE This path is no longer used and can be removed. --- clippy_utils/src/paths.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index 456b8019e95c..0e26b3bfd624 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -108,7 +108,6 @@ pub const VEC_DEQUE_ITER: [&str; 5] = ["alloc", "collections", "vec_deque", "Vec pub const VEC_FROM_ELEM: [&str; 3] = ["alloc", "vec", "from_elem"]; pub const VEC_NEW: [&str; 4] = ["alloc", "vec", "Vec", "new"]; pub const VEC_WITH_CAPACITY: [&str; 4] = ["alloc", "vec", "Vec", "with_capacity"]; -pub const VEC_RESIZE: [&str; 4] = ["alloc", "vec", "Vec", "resize"]; pub const INSTANT_NOW: [&str; 4] = ["std", "time", "Instant", "now"]; pub const VEC_IS_EMPTY: [&str; 4] = ["alloc", "vec", "Vec", "is_empty"]; pub const VEC_POP: [&str; 4] = ["alloc", "vec", "Vec", "pop"]; From 65d74785d7b43de0bae1e7687efbddbb4b170f91 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 1 May 2024 15:57:33 +0200 Subject: [PATCH 213/279] Align: add bytes_usize and bits_usize --- compiler/rustc_abi/src/lib.rs | 10 ++++++++++ compiler/rustc_transmute/src/layout/tree.rs | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index a46148242d5c..6a2943da4a3f 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -742,11 +742,21 @@ impl Align { 1 << self.pow2 } + #[inline] + pub fn bytes_usize(self) -> usize { + self.bytes().try_into().unwrap() + } + #[inline] pub fn bits(self) -> u64 { self.bytes() * 8 } + #[inline] + pub fn bits_usize(self) -> usize { + self.bits().try_into().unwrap() + } + /// Computes the best alignment possible for the given offset /// (the largest power of two that the offset is a multiple of). /// diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index edd3227210b2..604b68d2cd4a 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -266,7 +266,7 @@ pub(crate) mod rustc { ty::Ref(lifetime, ty, mutability) => { let ty_and_layout = cx.layout_of(*ty)?; - let align = ty_and_layout.align.abi.bytes() as usize; + let align = ty_and_layout.align.abi.bytes_usize(); let size = ty_and_layout.size.bytes_usize(); Ok(Tree::Ref(Ref { lifetime: *lifetime, From 712560cd0399bf36148ca8d185a2ed6e3cb2edb5 Mon Sep 17 00:00:00 2001 From: Urgau Date: Tue, 30 Apr 2024 22:40:19 +0200 Subject: [PATCH 214/279] Adjust `#[macro_export]`/doctest help suggestion for non_local_defs lint --- compiler/rustc_lint/messages.ftl | 2 ++ compiler/rustc_lint/src/lints.rs | 12 ++++++++---- compiler/rustc_lint/src/non_local_def.rs | 9 +++++++++ tests/rustdoc-ui/doctest/non_local_defs.rs | 10 ++++++++++ tests/rustdoc-ui/doctest/non_local_defs.stderr | 14 ++++++++++++++ tests/rustdoc-ui/doctest/non_local_defs.stdout | 6 ++++++ 6 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 tests/rustdoc-ui/doctest/non_local_defs.rs create mode 100644 tests/rustdoc-ui/doctest/non_local_defs.stderr create mode 100644 tests/rustdoc-ui/doctest/non_local_defs.stdout diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 82b90e1660a9..676a7c21841a 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -456,6 +456,8 @@ lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, th [one] `{$body_name}` *[other] `{$body_name}` and up {$depth} bodies } + .help_doctest = + remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() {"{"} ... {"}"}` .non_local = a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute .exception = one exception to the rule are anon-const (`const _: () = {"{"} ... {"}"}`) at top-level module diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 74a0a224dba4..7efa5245baa2 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1350,14 +1350,18 @@ pub enum NonLocalDefinitionsDiag { const_anon: Option, }, #[diag(lint_non_local_definitions_macro_rules)] - #[help] - #[note(lint_non_local)] - #[note(lint_exception)] - #[note(lint_non_local_definitions_deprecation)] MacroRules { depth: u32, body_kind_descr: &'static str, body_name: String, + #[help] + help: Option<()>, + #[help(lint_help_doctest)] + doctest_help: Option<()>, + #[note(lint_non_local)] + #[note(lint_exception)] + #[note(lint_non_local_definitions_deprecation)] + notes: (), #[subdiagnostic] cargo_update: Option, }, diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 004c2c2e4f44..27bf98018290 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -232,6 +232,12 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { ItemKind::Macro(_macro, MacroKind::Bang) if cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) => { + // determining we if are in a doctest context can't currently be determined + // by the code it-self (no specific attrs), but fortunatly rustdoc sets a + // perma-unstable env for libtest so we just re-use that env for now + let is_at_toplevel_doctest = + self.body_depth == 2 && std::env::var("UNSTABLE_RUSTDOC_TEST_PATH").is_ok(); + cx.emit_span_lint( NON_LOCAL_DEFINITIONS, item.span, @@ -242,6 +248,9 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { .map(|s| s.to_ident_string()) .unwrap_or_else(|| "".to_string()), cargo_update: cargo_update(), + help: (!is_at_toplevel_doctest).then_some(()), + doctest_help: is_at_toplevel_doctest.then_some(()), + notes: (), }, ) } diff --git a/tests/rustdoc-ui/doctest/non_local_defs.rs b/tests/rustdoc-ui/doctest/non_local_defs.rs new file mode 100644 index 000000000000..aa166c343b2b --- /dev/null +++ b/tests/rustdoc-ui/doctest/non_local_defs.rs @@ -0,0 +1,10 @@ +//@ check-pass +//@ compile-flags:--test --test-args --test-threads=1 --nocapture -Zunstable-options +//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stderr-test: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" + +//! ``` +//! #[macro_export] +//! macro_rules! a_macro { () => {} } +//! ``` diff --git a/tests/rustdoc-ui/doctest/non_local_defs.stderr b/tests/rustdoc-ui/doctest/non_local_defs.stderr new file mode 100644 index 000000000000..39a25de1aae7 --- /dev/null +++ b/tests/rustdoc-ui/doctest/non_local_defs.stderr @@ -0,0 +1,14 @@ +warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation + --> $DIR/non_local_defs.rs:9:1 + | +LL | macro_rules! a_macro { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() { ... }` + = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute + = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module + = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue + = note: `#[warn(non_local_definitions)]` on by default + +warning: 1 warning emitted + diff --git a/tests/rustdoc-ui/doctest/non_local_defs.stdout b/tests/rustdoc-ui/doctest/non_local_defs.stdout new file mode 100644 index 000000000000..bee195fcdd77 --- /dev/null +++ b/tests/rustdoc-ui/doctest/non_local_defs.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/non_local_defs.rs - (line 7) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + From f323f9dedb86e985e171eb64da109a5eb7bd55e4 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 1 May 2024 15:03:15 +0000 Subject: [PATCH 215/279] review --- .../src/solve/inspect/analyse.rs | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 00fe9bc12b5d..7c6dd4d3febc 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -41,19 +41,18 @@ pub struct InspectGoal<'a, 'tcx> { goal: Goal<'tcx, ty::Predicate<'tcx>>, result: Result, evaluation_kind: inspect::CanonicalGoalEvaluationKind<'tcx>, - /// The expected term of a `NormalizesTo` goal. It gets - /// replaced with an unconstrained inference variable when - /// computing `NormalizesTo` goals and we return the nested - /// goals to the caller, who also equates the actual term - /// with the expected. - /// - /// This is an implementation detail of the trait solver and - /// not something we want to leak to users. We therefore - /// treat `NormalizesTo` goals as if they apply the expected - /// type at the end of each candidate. normalizes_to_term_hack: Option>, } +/// The expected term of a `NormalizesTo` goal gets replaced +/// with an unconstrained inference variable when computing +/// `NormalizesTo` goals and we return the nested goals to the +/// caller, who also equates the actual term with the expected. +/// +/// This is an implementation detail of the trait solver and +/// not something we want to leak to users. We therefore +/// treat `NormalizesTo` goals as if they apply the expected +/// type at the end of each candidate. #[derive(Copy, Clone)] struct NormalizesToTermHack<'tcx> { term: ty::Term<'tcx>, @@ -61,7 +60,10 @@ struct NormalizesToTermHack<'tcx> { } impl<'tcx> NormalizesToTermHack<'tcx> { - fn relate( + /// Relate the `term` with the new `unconstrained_term` created + /// when computing the proof tree for this `NormalizesTo` goals. + /// This handles nested obligations. + fn constrain( self, infcx: &InferCtxt<'tcx>, span: Span, @@ -166,7 +168,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { // FIXME: We ignore the expected term of `NormalizesTo` goals // when computing the result of its candidates. This is // scuffed. - let _ = term_hack.relate(infcx, span, param_env); + let _ = term_hack.constrain(infcx, span, param_env); } instantiated_goals @@ -326,7 +328,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { let result = evaluation.result.and_then(|ok| { if let Some(term_hack) = normalizes_to_term_hack { infcx - .probe(|_| term_hack.relate(infcx, DUMMY_SP, uncanonicalized_goal.param_env)) + .probe(|_| term_hack.constrain(infcx, DUMMY_SP, uncanonicalized_goal.param_env)) .map(|certainty| ok.value.certainty.unify_with(certainty)) } else { Ok(ok.value.certainty) From 6115cf6f41e8b10afd0e2f0e0528d0463585d52e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 1 May 2024 17:11:49 +0200 Subject: [PATCH 216/279] always print nice 'std not found error' when std is not found --- compiler/rustc_metadata/src/errors.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index e8449d3918b7..fb0010f2c5d2 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -5,7 +5,6 @@ use std::{ use rustc_errors::{codes::*, Diag, DiagCtxt, Diagnostic, EmissionGuarantee, Level}; use rustc_macros::{Diagnostic, Subdiagnostic}; -use rustc_session::config; use rustc_span::{sym, Span, Symbol}; use rustc_target::spec::{PanicStrategy, TargetTriple}; @@ -640,9 +639,7 @@ impl Diagnostic<'_, G> for CannotFindCrate { diag.arg("locator_triple", self.locator_triple.triple()); diag.code(E0463); diag.span(self.span); - if (self.crate_name == sym::std || self.crate_name == sym::core) - && self.locator_triple != TargetTriple::from_triple(config::host_triple()) - { + if self.crate_name == sym::std || self.crate_name == sym::core { if self.missing_core { diag.note(fluent::metadata_target_not_installed); } else { From 9834c8307fd9fd5118f4f256258362bcaf0b46e7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 29 Apr 2024 11:53:06 -0400 Subject: [PATCH 217/279] Rewrite select to use a ProofTreeVisitor --- .../src/solve/eval_ctxt/select.rs | 510 ++++++------------ tests/ui/traits/dyn-any-prefer-vtable.rs | 9 + 2 files changed, 178 insertions(+), 341 deletions(-) create mode 100644 tests/ui/traits/dyn-any-prefer-vtable.rs diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs index 6de19df1067a..16fe045b82de 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs @@ -1,22 +1,17 @@ -use rustc_hir as hir; +use std::ops::ControlFlow; + use rustc_hir::def_id::DefId; -use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt}; +use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; +use rustc_infer::traits::solve::inspect::ProbeKind; +use rustc_infer::traits::solve::{CandidateSource, Certainty, Goal}; use rustc_infer::traits::{ - Obligation, PolyTraitObligation, PredicateObligation, Selection, SelectionResult, TraitEngine, + BuiltinImplSource, ImplSource, ImplSourceUserDefinedData, Obligation, ObligationCause, + PolyTraitObligation, PredicateObligation, Selection, SelectionError, SelectionResult, }; use rustc_macros::extension; -use rustc_middle::traits::solve::{CandidateSource, CanonicalInput, Certainty, Goal}; -use rustc_middle::traits::{ - BuiltinImplSource, ImplSource, ImplSourceUserDefinedData, ObligationCause, SelectionError, -}; -use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_span::DUMMY_SP; +use rustc_span::Span; -use crate::solve::assembly::Candidate; -use crate::solve::eval_ctxt::{EvalCtxt, GenerateProofTree}; -use crate::solve::inspect::ProofTreeBuilder; -use crate::traits::StructurallyNormalizeExt; -use crate::traits::TraitEngineExt; +use crate::solve::inspect::{self, ProofTreeInferCtxtExt}; #[extension(pub trait InferCtxtSelectExt<'tcx>)] impl<'tcx> InferCtxt<'tcx> { @@ -26,359 +21,192 @@ impl<'tcx> InferCtxt<'tcx> { ) -> SelectionResult<'tcx, Selection<'tcx>> { assert!(self.next_trait_solver()); - self.enter_forall(obligation.predicate, |pred| { - let trait_goal = Goal::new(self.tcx, obligation.param_env, pred); - - let (result, _) = EvalCtxt::enter_root(self, GenerateProofTree::Never, |ecx| { - let goal = Goal::new(ecx.tcx(), trait_goal.param_env, trait_goal.predicate); - let (orig_values, canonical_goal) = ecx.canonicalize_goal(goal); - let mut candidates = ecx.compute_canonical_trait_candidates(canonical_goal); - - // pseudo-winnow - if candidates.len() == 0 { - return Err(SelectionError::Unimplemented); - } else if candidates.len() > 1 { - let mut i = 0; - while i < candidates.len() { - let should_drop_i = (0..candidates.len()).filter(|&j| i != j).any(|j| { - candidate_should_be_dropped_in_favor_of( - ecx.tcx(), - &candidates[i], - &candidates[j], - ) - }); - if should_drop_i { - candidates.swap_remove(i); - } else { - i += 1; - if i > 1 { - return Ok(None); - } - } - } - } - - let candidate = candidates.pop().unwrap(); - let (normalization_nested_goals, certainty) = ecx - .instantiate_and_apply_query_response( - trait_goal.param_env, - orig_values, - candidate.result, - ); - assert!(normalization_nested_goals.is_empty()); - Ok(Some((candidate, certainty))) - }); - - let (candidate, certainty) = match result { - Ok(Some(result)) => result, - Ok(None) => return Ok(None), - Err(e) => return Err(e), - }; - - let goal = self.resolve_vars_if_possible(trait_goal); - match (certainty, candidate.source) { - // Rematching the implementation will instantiate the same nested goals that - // would have caused the ambiguity, so we can still make progress here regardless. - (_, CandidateSource::Impl(def_id)) => rematch_impl(self, goal, def_id), - - // If an unsize goal is ambiguous, then we can manually rematch it to make - // selection progress for coercion during HIR typeck. If it is *not* ambiguous, - // but is `BuiltinImplSource::Misc`, it may have nested `Unsize` goals, - // and we need to rematch those to detect tuple unsizing and trait upcasting. - // FIXME: This will be wrong if we have param-env or where-clause bounds - // with the unsize goal -- we may need to mark those with different impl - // sources. - (Certainty::Maybe(_), CandidateSource::BuiltinImpl(src)) - | (Certainty::Yes, CandidateSource::BuiltinImpl(src @ BuiltinImplSource::Misc)) - if self.tcx.lang_items().unsize_trait() == Some(goal.predicate.def_id()) => - { - rematch_unsize(self, goal, src, certainty) - } - - // Technically some builtin impls have nested obligations, but if - // `Certainty::Yes`, then they should've all been verified and don't - // need re-checking. - (Certainty::Yes, CandidateSource::BuiltinImpl(src)) => { - Ok(Some(ImplSource::Builtin(src, vec![]))) - } - - // It's fine not to do anything to rematch these, since there are no - // nested obligations. - (Certainty::Yes, CandidateSource::ParamEnv(_) | CandidateSource::AliasBound) => { - Ok(Some(ImplSource::Param(vec![]))) - } - - (_, CandidateSource::CoherenceUnknowable) => bug!(), - - (Certainty::Maybe(_), _) => Ok(None), - } - }) - } -} - -impl<'tcx> EvalCtxt<'_, 'tcx> { - fn compute_canonical_trait_candidates( - &mut self, - canonical_input: CanonicalInput<'tcx>, - ) -> Vec> { - // This doesn't record the canonical goal on the stack during the - // candidate assembly step, but that's fine. Selection is conceptually - // outside of the solver, and if there were any cycles, we'd encounter - // the cycle anyways one step later. - EvalCtxt::enter_canonical( - self.tcx(), - self.search_graph, - canonical_input, - // FIXME: This is wrong, idk if we even want to track stuff here. - &mut ProofTreeBuilder::new_noop(), - |ecx, goal| { - let trait_goal = Goal { - param_env: goal.param_env, - predicate: goal - .predicate - .to_opt_poly_trait_pred() - .expect("we canonicalized a trait goal") - .no_bound_vars() - .expect("we instantiated all bound vars"), - }; - ecx.assemble_and_evaluate_candidates(trait_goal) - }, + self.visit_proof_tree( + Goal::new(self.tcx, obligation.param_env, obligation.predicate), + &mut Select { span: obligation.cause.span }, ) + .break_value() + .unwrap() } } -fn candidate_should_be_dropped_in_favor_of<'tcx>( - tcx: TyCtxt<'tcx>, - victim: &Candidate<'tcx>, - other: &Candidate<'tcx>, -) -> bool { - match (victim.source, other.source) { - (CandidateSource::ParamEnv(victim_idx), CandidateSource::ParamEnv(other_idx)) => { - victim_idx >= other_idx - } - (_, CandidateSource::ParamEnv(_)) => true, +struct Select { + span: Span, +} - // FIXME: we could prefer earlier vtable bases perhaps... +impl<'tcx> inspect::ProofTreeVisitor<'tcx> for Select { + type Result = ControlFlow>>; + + fn span(&self) -> Span { + self.span + } + + fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result { + let mut candidates = goal.candidates(); + candidates.retain(|cand| cand.result().is_ok()); + + // No candidates -- not implemented. + if candidates.is_empty() { + return ControlFlow::Break(Err(SelectionError::Unimplemented)); + } + + // One candidate, no need to winnow. + if candidates.len() == 1 { + return ControlFlow::Break(Ok(to_selection( + self.span, + candidates.into_iter().next().unwrap(), + ))); + } + + // We need to winnow. See comments on `candidate_should_be_dropped_in_favor_of`. + let mut i = 0; + while i < candidates.len() { + let should_drop_i = (0..candidates.len()) + .filter(|&j| i != j) + .any(|j| candidate_should_be_dropped_in_favor_of(&candidates[i], &candidates[j])); + if should_drop_i { + candidates.swap_remove(i); + } else { + i += 1; + if i > 1 { + return ControlFlow::Break(Ok(None)); + } + } + } + + ControlFlow::Break(Ok(to_selection(self.span, candidates.into_iter().next().unwrap()))) + } +} + +/// This is a lot more limited than the old solver's equivalent method. This may lead to more `Ok(None)` +/// results when selecting traits in polymorphic contexts, but we should never rely on the lack of ambiguity, +/// and should always just gracefully fail here. We shouldn't rely on this incompleteness. +fn candidate_should_be_dropped_in_favor_of<'tcx>( + victim: &inspect::InspectCandidate<'_, 'tcx>, + other: &inspect::InspectCandidate<'_, 'tcx>, +) -> bool { + // Don't winnow until `Certainty::Yes` -- we don't need to winnow until + // codegen, technically. + if matches!(other.result().unwrap(), Certainty::Maybe(..)) { + return false; + } + + let inspect::ProbeKind::TraitCandidate { source: victim_source, result: _ } = victim.kind() + else { + return false; + }; + let inspect::ProbeKind::TraitCandidate { source: other_source, result: _ } = other.kind() + else { + return false; + }; + + match (victim_source, other_source) { + (_, CandidateSource::CoherenceUnknowable) | (CandidateSource::CoherenceUnknowable, _) => { + bug!("should not have assembled a CoherenceUnknowable candidate") + } + + // Prefer dyn candidates over non-dyn candidates. This is necessary to + // handle the unsoundness between `impl Any for T` and `dyn Any: Any`. ( CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. }), CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. }), ) => false, - (_, CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. })) => true, + ( + CandidateSource::Impl(_) | CandidateSource::ParamEnv(_) | CandidateSource::AliasBound, + CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. }), + ) => true, + // Prefer specializing candidates over specialized candidates. (CandidateSource::Impl(victim_def_id), CandidateSource::Impl(other_def_id)) => { - tcx.specializes((other_def_id, victim_def_id)) - && other.result.value.certainty == Certainty::Yes + victim.goal().infcx().tcx.specializes((other_def_id, victim_def_id)) } _ => false, } } +fn to_selection<'tcx>( + span: Span, + cand: inspect::InspectCandidate<'_, 'tcx>, +) -> Option> { + if let Certainty::Maybe(..) = cand.shallow_certainty() { + return None; + } + + let make_nested = || { + cand.instantiate_nested_goals(span) + .into_iter() + .map(|nested| { + Obligation::new( + nested.infcx().tcx, + ObligationCause::dummy_with_span(span), + nested.goal().param_env, + nested.goal().predicate, + ) + }) + .collect() + }; + + Some(match cand.kind() { + ProbeKind::TraitCandidate { source, result: _ } => match source { + CandidateSource::Impl(impl_def_id) => { + // FIXME: Remove this in favor of storing this in the tree + // For impl candidates, we do the rematch manually to compute the args. + ImplSource::UserDefined(rematch_impl(cand.goal(), impl_def_id, span)) + } + CandidateSource::BuiltinImpl(builtin) => ImplSource::Builtin(builtin, make_nested()), + CandidateSource::ParamEnv(_) => ImplSource::Param(make_nested()), + CandidateSource::AliasBound => { + ImplSource::Builtin(BuiltinImplSource::Misc, make_nested()) + } + CandidateSource::CoherenceUnknowable => { + span_bug!(span, "didn't expect to select an unknowable candidate") + } + }, + ProbeKind::TryNormalizeNonRigid { result: _ } + | ProbeKind::NormalizedSelfTyAssembly + | ProbeKind::UnsizeAssembly + | ProbeKind::UpcastProjectionCompatibility + | ProbeKind::OpaqueTypeStorageLookup { result: _ } + | ProbeKind::Root { result: _ } => { + span_bug!(span, "didn't expect to assemble trait candidate from {:#?}", cand.kind()) + } + }) +} + fn rematch_impl<'tcx>( - infcx: &InferCtxt<'tcx>, - goal: Goal<'tcx, ty::TraitPredicate<'tcx>>, + goal: &inspect::InspectGoal<'_, 'tcx>, impl_def_id: DefId, -) -> SelectionResult<'tcx, Selection<'tcx>> { - let args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id); + span: Span, +) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> { + let infcx = goal.infcx(); + let goal_trait_ref = infcx + .enter_forall_and_leak_universe(goal.goal().predicate.to_opt_poly_trait_pred().unwrap()) + .trait_ref; + + let args = infcx.fresh_args_for_item(span, impl_def_id); let impl_trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(infcx.tcx, args); - let mut nested = infcx - .at(&ObligationCause::dummy(), goal.param_env) - // New solver ignores DefineOpaqueTypes, so choose Yes for consistency - .eq(DefineOpaqueTypes::Yes, goal.predicate.trait_ref, impl_trait_ref) - .map_err(|_| SelectionError::Unimplemented)? - .into_obligations(); + let InferOk { value: (), obligations: mut nested } = infcx + .at(&ObligationCause::dummy_with_span(span), goal.goal().param_env) + .eq(DefineOpaqueTypes::Yes, goal_trait_ref, impl_trait_ref) + .expect("rematching impl failed"); + + // FIXME(-Znext-solver=coinductive): We need to add supertraits here eventually. nested.extend( infcx.tcx.predicates_of(impl_def_id).instantiate(infcx.tcx, args).into_iter().map( - |(pred, _)| Obligation::new(infcx.tcx, ObligationCause::dummy(), goal.param_env, pred), + |(clause, _)| { + Obligation::new( + infcx.tcx, + ObligationCause::dummy_with_span(span), + goal.goal().param_env, + clause, + ) + }, ), ); - Ok(Some(ImplSource::UserDefined(ImplSourceUserDefinedData { impl_def_id, args, nested }))) -} - -/// The `Unsize` trait is particularly important to coercion, so we try rematch it. -/// NOTE: This must stay in sync with `consider_builtin_unsize_candidate` in trait -/// goal assembly in the solver, both for soundness and in order to avoid ICEs. -fn rematch_unsize<'tcx>( - infcx: &InferCtxt<'tcx>, - goal: Goal<'tcx, ty::TraitPredicate<'tcx>>, - source: BuiltinImplSource, - certainty: Certainty, -) -> SelectionResult<'tcx, Selection<'tcx>> { - let tcx = infcx.tcx; - let mut nested = vec![]; - let a_ty = structurally_normalize(goal.predicate.self_ty(), infcx, goal.param_env, &mut nested); - let b_ty = structurally_normalize( - goal.predicate.trait_ref.args.type_at(1), - infcx, - goal.param_env, - &mut nested, - ); - - match (a_ty.kind(), b_ty.kind()) { - // Don't try to coerce `?0` to `dyn Trait` - (ty::Infer(ty::TyVar(_)), _) | (_, ty::Infer(ty::TyVar(_))) => Ok(None), - // Stall any ambiguous upcasting goals, since we can't rematch those - (ty::Dynamic(_, _, ty::Dyn), ty::Dynamic(_, _, ty::Dyn)) => match certainty { - Certainty::Yes => Ok(Some(ImplSource::Builtin(source, nested))), - _ => Ok(None), - }, - // `T` -> `dyn Trait` upcasting - (_, &ty::Dynamic(data, region, ty::Dyn)) => { - // Check that the type implements all of the predicates of the def-id. - // (i.e. the principal, all of the associated types match, and any auto traits) - nested.extend(data.iter().map(|pred| { - Obligation::new( - infcx.tcx, - ObligationCause::dummy(), - goal.param_env, - pred.with_self_ty(tcx, a_ty), - ) - })); - // The type must be Sized to be unsized. - let sized_def_id = tcx.require_lang_item(hir::LangItem::Sized, None); - nested.push(Obligation::new( - infcx.tcx, - ObligationCause::dummy(), - goal.param_env, - ty::TraitRef::new(tcx, sized_def_id, [a_ty]), - )); - // The type must outlive the lifetime of the `dyn` we're unsizing into. - nested.push(Obligation::new( - infcx.tcx, - ObligationCause::dummy(), - goal.param_env, - ty::OutlivesPredicate(a_ty, region), - )); - - Ok(Some(ImplSource::Builtin(source, nested))) - } - // `[T; n]` -> `[T]` unsizing - (&ty::Array(a_elem_ty, ..), &ty::Slice(b_elem_ty)) => { - nested.extend( - infcx - .at(&ObligationCause::dummy(), goal.param_env) - // New solver ignores DefineOpaqueTypes, so choose Yes for consistency - .eq(DefineOpaqueTypes::Yes, a_elem_ty, b_elem_ty) - .expect("expected rematch to succeed") - .into_obligations(), - ); - - Ok(Some(ImplSource::Builtin(source, nested))) - } - // Struct unsizing `Struct` -> `Struct` where `T: Unsize` - (&ty::Adt(a_def, a_args), &ty::Adt(b_def, b_args)) - if a_def.is_struct() && a_def.did() == b_def.did() => - { - let unsizing_params = tcx.unsizing_params_for_adt(a_def.did()); - // We must be unsizing some type parameters. This also implies - // that the struct has a tail field. - if unsizing_params.is_empty() { - bug!("expected rematch to succeed") - } - - let tail_field = a_def - .non_enum_variant() - .fields - .raw - .last() - .expect("expected unsized ADT to have a tail field"); - let tail_field_ty = tcx.type_of(tail_field.did); - - let a_tail_ty = tail_field_ty.instantiate(tcx, a_args); - let b_tail_ty = tail_field_ty.instantiate(tcx, b_args); - - // Instantiate just the unsizing params from B into A. The type after - // this instantiation must be equal to B. This is so we don't unsize - // unrelated type parameters. - let new_a_args = tcx.mk_args_from_iter( - a_args - .iter() - .enumerate() - .map(|(i, a)| if unsizing_params.contains(i as u32) { b_args[i] } else { a }), - ); - let unsized_a_ty = Ty::new_adt(tcx, a_def, new_a_args); - - nested.extend( - infcx - .at(&ObligationCause::dummy(), goal.param_env) - // New solver ignores DefineOpaqueTypes, so choose Yes for consistency - .eq(DefineOpaqueTypes::Yes, unsized_a_ty, b_ty) - .expect("expected rematch to succeed") - .into_obligations(), - ); - - // Finally, we require that `TailA: Unsize` for the tail field - // types. - nested.push(Obligation::new( - tcx, - ObligationCause::dummy(), - goal.param_env, - ty::TraitRef::new(tcx, goal.predicate.def_id(), [a_tail_ty, b_tail_ty]), - )); - - Ok(Some(ImplSource::Builtin(source, nested))) - } - // Tuple unsizing `(.., T)` -> `(.., U)` where `T: Unsize` - (&ty::Tuple(a_tys), &ty::Tuple(b_tys)) - if a_tys.len() == b_tys.len() && !a_tys.is_empty() => - { - let (a_last_ty, a_rest_tys) = a_tys.split_last().unwrap(); - let b_last_ty = b_tys.last().unwrap(); - - // Instantiate just the tail field of B., and require that they're equal. - let unsized_a_ty = - Ty::new_tup_from_iter(tcx, a_rest_tys.iter().chain([b_last_ty]).copied()); - nested.extend( - infcx - .at(&ObligationCause::dummy(), goal.param_env) - // New solver ignores DefineOpaqueTypes, so choose Yes for consistency - .eq(DefineOpaqueTypes::Yes, unsized_a_ty, b_ty) - .expect("expected rematch to succeed") - .into_obligations(), - ); - - // Similar to ADTs, require that we can unsize the tail. - nested.push(Obligation::new( - tcx, - ObligationCause::dummy(), - goal.param_env, - ty::TraitRef::new(tcx, goal.predicate.def_id(), [*a_last_ty, *b_last_ty]), - )); - - // We need to be able to detect tuple unsizing to require its feature gate. - assert_eq!( - source, - BuiltinImplSource::TupleUnsizing, - "compiler-errors wants to know if this can ever be triggered..." - ); - Ok(Some(ImplSource::Builtin(source, nested))) - } - _ => { - assert_ne!(certainty, Certainty::Yes); - Ok(None) - } - } -} - -fn structurally_normalize<'tcx>( - ty: Ty<'tcx>, - infcx: &InferCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - nested: &mut Vec>, -) -> Ty<'tcx> { - if matches!(ty.kind(), ty::Alias(..)) { - let mut engine = >::new(infcx); - let normalized_ty = infcx - .at(&ObligationCause::dummy(), param_env) - .structurally_normalize(ty, &mut *engine) - .expect("normalization shouldn't fail if we got to here"); - nested.extend(engine.pending_obligations()); - normalized_ty - } else { - ty - } + ImplSourceUserDefinedData { impl_def_id, nested, args } } diff --git a/tests/ui/traits/dyn-any-prefer-vtable.rs b/tests/ui/traits/dyn-any-prefer-vtable.rs new file mode 100644 index 000000000000..ca9d655239d8 --- /dev/null +++ b/tests/ui/traits/dyn-any-prefer-vtable.rs @@ -0,0 +1,9 @@ +//@ run-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +fn main() { + let x: &dyn std::any::Any = &1i32; + assert_eq!(x.type_id(), std::any::TypeId::of::()); +} From 706f06c39a9e08a4708a53722429d13ae4069c2f Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 1 May 2024 15:25:26 -0700 Subject: [PATCH 218/279] Use an explicit x86-64 cpu in tests that are sensitive to it There are a few tests that depend on some target features **not** being enabled by default, and usually they are correct with the default x86-64 target CPU. However, in downstream builds we have modified the default to fit our distros -- `x86-64-v2` in RHEL 9 and `x86-64-v3` in RHEL 10 -- and the latter especially trips tests that expect not to have AVX. These cases are few enough that we can just set them back explicitly. --- tests/assembly/simd-intrinsic-mask-reduce.rs | 1 + tests/assembly/x86_64-floating-point-clamp.rs | 2 +- .../codegen/target-feature-inline-closure.rs | 2 +- tests/ui/asm/x86_64/target-feature-attr.rs | 1 + .../ui/asm/x86_64/target-feature-attr.stderr | 8 +++--- .../const-eval/const_fn_target_feature.rs | 2 +- .../rfc-2396-target_feature-11/safe-calls.rs | 1 + .../safe-calls.stderr | 28 +++++++++---------- tests/ui/sse2.rs | 4 +-- 9 files changed, 26 insertions(+), 23 deletions(-) diff --git a/tests/assembly/simd-intrinsic-mask-reduce.rs b/tests/assembly/simd-intrinsic-mask-reduce.rs index 763401755fad..0d77fc410511 100644 --- a/tests/assembly/simd-intrinsic-mask-reduce.rs +++ b/tests/assembly/simd-intrinsic-mask-reduce.rs @@ -1,6 +1,7 @@ // verify that simd mask reductions do not introduce additional bit shift operations //@ revisions: x86 aarch64 //@ [x86] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel +//@ [x86] compile-flags: -C target-cpu=x86-64 //@ [x86] needs-llvm-components: x86 //@ [aarch64] compile-flags: --target=aarch64-unknown-linux-gnu //@ [aarch64] needs-llvm-components: aarch64 diff --git a/tests/assembly/x86_64-floating-point-clamp.rs b/tests/assembly/x86_64-floating-point-clamp.rs index 4a72a7f44fa0..b963aee35590 100644 --- a/tests/assembly/x86_64-floating-point-clamp.rs +++ b/tests/assembly/x86_64-floating-point-clamp.rs @@ -2,7 +2,7 @@ // so check to make sure that's what it's actually emitting. //@ assembly-output: emit-asm -//@ compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel +//@ compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel -C target-cpu=x86-64 //@ only-x86_64 //@ ignore-sgx diff --git a/tests/codegen/target-feature-inline-closure.rs b/tests/codegen/target-feature-inline-closure.rs index 88bd413a8707..20bb4e66ff21 100644 --- a/tests/codegen/target-feature-inline-closure.rs +++ b/tests/codegen/target-feature-inline-closure.rs @@ -1,5 +1,5 @@ //@ only-x86_64 -//@ compile-flags: -Copt-level=3 +//@ compile-flags: -Copt-level=3 -Ctarget-cpu=x86-64 #![crate_type = "lib"] #![feature(target_feature_11)] diff --git a/tests/ui/asm/x86_64/target-feature-attr.rs b/tests/ui/asm/x86_64/target-feature-attr.rs index 820be132ef79..51829be15065 100644 --- a/tests/ui/asm/x86_64/target-feature-attr.rs +++ b/tests/ui/asm/x86_64/target-feature-attr.rs @@ -1,4 +1,5 @@ //@ only-x86_64 +//@ compile-flags: -C target-cpu=x86-64 #![feature(avx512_target_feature)] diff --git a/tests/ui/asm/x86_64/target-feature-attr.stderr b/tests/ui/asm/x86_64/target-feature-attr.stderr index c852726ee7ff..1a9962732cfb 100644 --- a/tests/ui/asm/x86_64/target-feature-attr.stderr +++ b/tests/ui/asm/x86_64/target-feature-attr.stderr @@ -1,23 +1,23 @@ error: register class `ymm_reg` requires the `avx` target feature - --> $DIR/target-feature-attr.rs:18:40 + --> $DIR/target-feature-attr.rs:19:40 | LL | asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x); | ^^^^^^^^^^^^^ error: register class `ymm_reg` requires the `avx` target feature - --> $DIR/target-feature-attr.rs:18:55 + --> $DIR/target-feature-attr.rs:19:55 | LL | asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x); | ^^^^^^^^^^^^^ error: register class `ymm_reg` requires the `avx` target feature - --> $DIR/target-feature-attr.rs:18:70 + --> $DIR/target-feature-attr.rs:19:70 | LL | asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x); | ^^^^^^^^^^^^^^^^^^ error: register class `kreg` requires at least one of the following target features: avx512bw, avx512f - --> $DIR/target-feature-attr.rs:33:23 + --> $DIR/target-feature-attr.rs:34:23 | LL | asm!("/* {0} */", in(kreg) x); | ^^^^^^^^^^ diff --git a/tests/ui/consts/const-eval/const_fn_target_feature.rs b/tests/ui/consts/const-eval/const_fn_target_feature.rs index b56b68a57958..d0de9d8d7a34 100644 --- a/tests/ui/consts/const-eval/const_fn_target_feature.rs +++ b/tests/ui/consts/const-eval/const_fn_target_feature.rs @@ -1,5 +1,5 @@ //@ only-x86_64 -//@ compile-flags:-C target-feature=+ssse3 +//@ compile-flags: -C target-cpu=x86-64 -C target-feature=+ssse3 #![crate_type = "lib"] diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs index c73b8d7e4d29..6fb0688008e6 100644 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs +++ b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs @@ -1,4 +1,5 @@ //@ only-x86_64 +//@ compile-flags: -C target-cpu=x86-64 #![feature(target_feature_11)] diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr index d9d7e297f8e9..fed3da6594cb 100644 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr +++ b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr @@ -1,5 +1,5 @@ error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:25:5 + --> $DIR/safe-calls.rs:26:5 | LL | sse2(); | ^^^^^^ call to function with `#[target_feature]` @@ -8,7 +8,7 @@ LL | sse2(); = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:27:5 + --> $DIR/safe-calls.rs:28:5 | LL | avx_bmi2(); | ^^^^^^^^^^ call to function with `#[target_feature]` @@ -16,7 +16,7 @@ LL | avx_bmi2(); = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:29:5 + --> $DIR/safe-calls.rs:30:5 | LL | Quux.avx_bmi2(); | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` @@ -24,7 +24,7 @@ LL | Quux.avx_bmi2(); = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:35:5 + --> $DIR/safe-calls.rs:36:5 | LL | avx_bmi2(); | ^^^^^^^^^^ call to function with `#[target_feature]` @@ -32,7 +32,7 @@ LL | avx_bmi2(); = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:37:5 + --> $DIR/safe-calls.rs:38:5 | LL | Quux.avx_bmi2(); | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` @@ -40,7 +40,7 @@ LL | Quux.avx_bmi2(); = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:43:5 + --> $DIR/safe-calls.rs:44:5 | LL | sse2(); | ^^^^^^ call to function with `#[target_feature]` @@ -49,7 +49,7 @@ LL | sse2(); = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:45:5 + --> $DIR/safe-calls.rs:46:5 | LL | avx_bmi2(); | ^^^^^^^^^^ call to function with `#[target_feature]` @@ -57,7 +57,7 @@ LL | avx_bmi2(); = help: in order for the call to be safe, the context requires the following additional target feature: bmi2 error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:47:5 + --> $DIR/safe-calls.rs:48:5 | LL | Quux.avx_bmi2(); | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` @@ -65,7 +65,7 @@ LL | Quux.avx_bmi2(); = help: in order for the call to be safe, the context requires the following additional target feature: bmi2 error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:54:5 + --> $DIR/safe-calls.rs:55:5 | LL | sse2(); | ^^^^^^ call to function with `#[target_feature]` @@ -74,7 +74,7 @@ LL | sse2(); = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:58:15 + --> $DIR/safe-calls.rs:59:15 | LL | const _: () = sse2(); | ^^^^^^ call to function with `#[target_feature]` @@ -83,7 +83,7 @@ LL | const _: () = sse2(); = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` error[E0133]: call to function `sse2_and_fxsr` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:61:15 + --> $DIR/safe-calls.rs:62:15 | LL | const _: () = sse2_and_fxsr(); | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` @@ -92,7 +92,7 @@ LL | const _: () = sse2_and_fxsr(); = note: the fxsr and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]` error: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe block (error E0133) - --> $DIR/safe-calls.rs:68:5 + --> $DIR/safe-calls.rs:69:5 | LL | sse2(); | ^^^^^^ call to function with `#[target_feature]` @@ -101,12 +101,12 @@ LL | sse2(); = help: in order for the call to be safe, the context requires the following additional target feature: sse2 = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` note: an unsafe function restricts its caller, but its body is safe by default - --> $DIR/safe-calls.rs:67:1 + --> $DIR/safe-calls.rs:68:1 | LL | unsafe fn needs_unsafe_block() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: the lint level is defined here - --> $DIR/safe-calls.rs:64:8 + --> $DIR/safe-calls.rs:65:8 | LL | #[deny(unsafe_op_in_unsafe_fn)] | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/sse2.rs b/tests/ui/sse2.rs index fa6d79713b4b..c203ca2716ff 100644 --- a/tests/ui/sse2.rs +++ b/tests/ui/sse2.rs @@ -20,6 +20,6 @@ fn main() { "SSE2 was not detected as available on an x86 platform"); } // check a negative case too -- allowed on x86, but not enabled by default - assert!(cfg!(not(target_feature = "avx2")), - "AVX2 shouldn't be detected as available by default on any platform"); + assert!(cfg!(not(target_feature = "avx512f")), + "AVX512 shouldn't be detected as available by default on any platform"); } From 1b79bb937f399e82768ea90fb0d0b4ffd5a915d4 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 1 May 2024 16:54:20 -0700 Subject: [PATCH 219/279] Add inline comments why we're forcing the target cpu --- tests/assembly/simd-intrinsic-mask-reduce.rs | 1 + tests/assembly/x86_64-floating-point-clamp.rs | 1 + .../codegen/target-feature-inline-closure.rs | 1 + tests/ui/asm/x86_64/target-feature-attr.rs | 1 + .../ui/asm/x86_64/target-feature-attr.stderr | 8 +++--- .../const-eval/const_fn_target_feature.rs | 1 + .../const-eval/const_fn_target_feature.stderr | 2 +- .../rfc-2396-target_feature-11/safe-calls.rs | 1 + .../safe-calls.stderr | 28 +++++++++---------- 9 files changed, 25 insertions(+), 19 deletions(-) diff --git a/tests/assembly/simd-intrinsic-mask-reduce.rs b/tests/assembly/simd-intrinsic-mask-reduce.rs index 0d77fc410511..72c3f6376e80 100644 --- a/tests/assembly/simd-intrinsic-mask-reduce.rs +++ b/tests/assembly/simd-intrinsic-mask-reduce.rs @@ -1,6 +1,7 @@ // verify that simd mask reductions do not introduce additional bit shift operations //@ revisions: x86 aarch64 //@ [x86] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel +// Set the base cpu explicitly, in case the default has been changed. //@ [x86] compile-flags: -C target-cpu=x86-64 //@ [x86] needs-llvm-components: x86 //@ [aarch64] compile-flags: --target=aarch64-unknown-linux-gnu diff --git a/tests/assembly/x86_64-floating-point-clamp.rs b/tests/assembly/x86_64-floating-point-clamp.rs index b963aee35590..c05afadff645 100644 --- a/tests/assembly/x86_64-floating-point-clamp.rs +++ b/tests/assembly/x86_64-floating-point-clamp.rs @@ -2,6 +2,7 @@ // so check to make sure that's what it's actually emitting. //@ assembly-output: emit-asm +// Set the base cpu explicitly, in case the default has been changed. //@ compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel -C target-cpu=x86-64 //@ only-x86_64 //@ ignore-sgx diff --git a/tests/codegen/target-feature-inline-closure.rs b/tests/codegen/target-feature-inline-closure.rs index 20bb4e66ff21..d973bd93e316 100644 --- a/tests/codegen/target-feature-inline-closure.rs +++ b/tests/codegen/target-feature-inline-closure.rs @@ -1,4 +1,5 @@ //@ only-x86_64 +// Set the base cpu explicitly, in case the default has been changed. //@ compile-flags: -Copt-level=3 -Ctarget-cpu=x86-64 #![crate_type = "lib"] diff --git a/tests/ui/asm/x86_64/target-feature-attr.rs b/tests/ui/asm/x86_64/target-feature-attr.rs index 51829be15065..6bb277ac1659 100644 --- a/tests/ui/asm/x86_64/target-feature-attr.rs +++ b/tests/ui/asm/x86_64/target-feature-attr.rs @@ -1,4 +1,5 @@ //@ only-x86_64 +// Set the base cpu explicitly, in case the default has been changed. //@ compile-flags: -C target-cpu=x86-64 #![feature(avx512_target_feature)] diff --git a/tests/ui/asm/x86_64/target-feature-attr.stderr b/tests/ui/asm/x86_64/target-feature-attr.stderr index 1a9962732cfb..0cd571ac8cce 100644 --- a/tests/ui/asm/x86_64/target-feature-attr.stderr +++ b/tests/ui/asm/x86_64/target-feature-attr.stderr @@ -1,23 +1,23 @@ error: register class `ymm_reg` requires the `avx` target feature - --> $DIR/target-feature-attr.rs:19:40 + --> $DIR/target-feature-attr.rs:20:40 | LL | asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x); | ^^^^^^^^^^^^^ error: register class `ymm_reg` requires the `avx` target feature - --> $DIR/target-feature-attr.rs:19:55 + --> $DIR/target-feature-attr.rs:20:55 | LL | asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x); | ^^^^^^^^^^^^^ error: register class `ymm_reg` requires the `avx` target feature - --> $DIR/target-feature-attr.rs:19:70 + --> $DIR/target-feature-attr.rs:20:70 | LL | asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x); | ^^^^^^^^^^^^^^^^^^ error: register class `kreg` requires at least one of the following target features: avx512bw, avx512f - --> $DIR/target-feature-attr.rs:34:23 + --> $DIR/target-feature-attr.rs:35:23 | LL | asm!("/* {0} */", in(kreg) x); | ^^^^^^^^^^ diff --git a/tests/ui/consts/const-eval/const_fn_target_feature.rs b/tests/ui/consts/const-eval/const_fn_target_feature.rs index d0de9d8d7a34..ee669abb51e5 100644 --- a/tests/ui/consts/const-eval/const_fn_target_feature.rs +++ b/tests/ui/consts/const-eval/const_fn_target_feature.rs @@ -1,4 +1,5 @@ //@ only-x86_64 +// Set the base cpu explicitly, in case the default has been changed. //@ compile-flags: -C target-cpu=x86-64 -C target-feature=+ssse3 #![crate_type = "lib"] diff --git a/tests/ui/consts/const-eval/const_fn_target_feature.stderr b/tests/ui/consts/const-eval/const_fn_target_feature.stderr index 0c7c69b794aa..d3a00b57ebb5 100644 --- a/tests/ui/consts/const-eval/const_fn_target_feature.stderr +++ b/tests/ui/consts/const-eval/const_fn_target_feature.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation of constant value failed - --> $DIR/const_fn_target_feature.rs:10:24 + --> $DIR/const_fn_target_feature.rs:11:24 | LL | const B: () = unsafe { avx2_fn() }; | ^^^^^^^^^ calling a function that requires unavailable target features: avx2 diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs index 6fb0688008e6..de002ef71d7d 100644 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs +++ b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs @@ -1,4 +1,5 @@ //@ only-x86_64 +// Set the base cpu explicitly, in case the default has been changed. //@ compile-flags: -C target-cpu=x86-64 #![feature(target_feature_11)] diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr index fed3da6594cb..aa660db38679 100644 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr +++ b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr @@ -1,5 +1,5 @@ error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:26:5 + --> $DIR/safe-calls.rs:27:5 | LL | sse2(); | ^^^^^^ call to function with `#[target_feature]` @@ -8,7 +8,7 @@ LL | sse2(); = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:28:5 + --> $DIR/safe-calls.rs:29:5 | LL | avx_bmi2(); | ^^^^^^^^^^ call to function with `#[target_feature]` @@ -16,7 +16,7 @@ LL | avx_bmi2(); = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:30:5 + --> $DIR/safe-calls.rs:31:5 | LL | Quux.avx_bmi2(); | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` @@ -24,7 +24,7 @@ LL | Quux.avx_bmi2(); = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:36:5 + --> $DIR/safe-calls.rs:37:5 | LL | avx_bmi2(); | ^^^^^^^^^^ call to function with `#[target_feature]` @@ -32,7 +32,7 @@ LL | avx_bmi2(); = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:38:5 + --> $DIR/safe-calls.rs:39:5 | LL | Quux.avx_bmi2(); | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` @@ -40,7 +40,7 @@ LL | Quux.avx_bmi2(); = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:44:5 + --> $DIR/safe-calls.rs:45:5 | LL | sse2(); | ^^^^^^ call to function with `#[target_feature]` @@ -49,7 +49,7 @@ LL | sse2(); = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:46:5 + --> $DIR/safe-calls.rs:47:5 | LL | avx_bmi2(); | ^^^^^^^^^^ call to function with `#[target_feature]` @@ -57,7 +57,7 @@ LL | avx_bmi2(); = help: in order for the call to be safe, the context requires the following additional target feature: bmi2 error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:48:5 + --> $DIR/safe-calls.rs:49:5 | LL | Quux.avx_bmi2(); | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` @@ -65,7 +65,7 @@ LL | Quux.avx_bmi2(); = help: in order for the call to be safe, the context requires the following additional target feature: bmi2 error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:55:5 + --> $DIR/safe-calls.rs:56:5 | LL | sse2(); | ^^^^^^ call to function with `#[target_feature]` @@ -74,7 +74,7 @@ LL | sse2(); = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:59:15 + --> $DIR/safe-calls.rs:60:15 | LL | const _: () = sse2(); | ^^^^^^ call to function with `#[target_feature]` @@ -83,7 +83,7 @@ LL | const _: () = sse2(); = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` error[E0133]: call to function `sse2_and_fxsr` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:62:15 + --> $DIR/safe-calls.rs:63:15 | LL | const _: () = sse2_and_fxsr(); | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` @@ -92,7 +92,7 @@ LL | const _: () = sse2_and_fxsr(); = note: the fxsr and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]` error: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe block (error E0133) - --> $DIR/safe-calls.rs:69:5 + --> $DIR/safe-calls.rs:70:5 | LL | sse2(); | ^^^^^^ call to function with `#[target_feature]` @@ -101,12 +101,12 @@ LL | sse2(); = help: in order for the call to be safe, the context requires the following additional target feature: sse2 = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` note: an unsafe function restricts its caller, but its body is safe by default - --> $DIR/safe-calls.rs:68:1 + --> $DIR/safe-calls.rs:69:1 | LL | unsafe fn needs_unsafe_block() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: the lint level is defined here - --> $DIR/safe-calls.rs:65:8 + --> $DIR/safe-calls.rs:66:8 | LL | #[deny(unsafe_op_in_unsafe_fn)] | ^^^^^^^^^^^^^^^^^^^^^^ From 393d9334d986a21ab1c7a6c4fe0c5f4f550aa3cc Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 1 May 2024 16:55:10 -0700 Subject: [PATCH 220/279] Use an outlandish target feature for the negative case --- tests/ui/sse2.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ui/sse2.rs b/tests/ui/sse2.rs index c203ca2716ff..60570c566dea 100644 --- a/tests/ui/sse2.rs +++ b/tests/ui/sse2.rs @@ -19,7 +19,7 @@ fn main() { assert!(cfg!(target_feature = "sse2"), "SSE2 was not detected as available on an x86 platform"); } - // check a negative case too -- allowed on x86, but not enabled by default - assert!(cfg!(not(target_feature = "avx512f")), - "AVX512 shouldn't be detected as available by default on any platform"); + // check a negative case too -- certainly not enabled by default + assert!(cfg!(not(target_feature = "ferris_wheel")), + "🎡 shouldn't be detected as available by default on any platform"); } From bd7d328807a8bb15732ebb764e1ea3df4fbe3fd1 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 28 Apr 2024 09:28:27 -0400 Subject: [PATCH 221/279] Replace version placeholders for 1.79 --- compiler/rustc_feature/src/accepted.rs | 10 +++++----- compiler/rustc_feature/src/unstable.rs | 18 +++++++++--------- library/alloc/src/str.rs | 2 +- library/core/src/ffi/c_str.rs | 2 +- library/core/src/intrinsics.rs | 8 ++++---- library/core/src/iter/traits/collect.rs | 2 +- library/core/src/num/int_macros.rs | 12 ++++++------ library/core/src/num/mod.rs | 2 +- library/core/src/num/nonzero.rs | 6 +++--- library/core/src/num/uint_macros.rs | 12 ++++++------ library/core/src/panic/location.rs | 8 ++++---- library/core/src/ptr/const_ptr.rs | 10 +++++----- library/core/src/ptr/mut_ptr.rs | 10 +++++----- library/core/src/ptr/non_null.rs | 9 +++------ library/core/src/slice/mod.rs | 4 ++-- library/core/src/str/lossy.rs | 16 ++++++++-------- library/core/src/str/mod.rs | 2 +- library/core/src/sync/atomic.rs | 6 +++--- library/proc_macro/src/lib.rs | 4 ++-- library/std/src/io/cursor.rs | 6 +++--- library/std/src/io/error.rs | 2 +- library/std/src/io/util.rs | 6 +++--- library/std/src/num.rs | 2 +- library/std/src/path.rs | 2 +- 24 files changed, 79 insertions(+), 82 deletions(-) diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index de2bd60ffad8..943cc6328578 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -60,7 +60,7 @@ declare_features! ( /// Allows the definition of associated constants in `trait` or `impl` blocks. (accepted, associated_consts, "1.20.0", Some(29646)), /// Allows the user of associated type bounds. - (accepted, associated_type_bounds, "CURRENT_RUSTC_VERSION", Some(52662)), + (accepted, associated_type_bounds, "1.79.0", Some(52662)), /// Allows using associated `type`s in `trait`s. (accepted, associated_types, "1.0.0", None), /// Allows free and inherent `async fn`s, `async` blocks, and `.await` expressions. @@ -99,7 +99,7 @@ declare_features! ( /// Allows using the CMPXCHG16B target feature. (accepted, cmpxchg16b_target_feature, "1.69.0", Some(44839)), /// Allows use of the `#[collapse_debuginfo]` attribute. - (accepted, collapse_debuginfo, "CURRENT_RUSTC_VERSION", Some(100758)), + (accepted, collapse_debuginfo, "1.79.0", Some(100758)), /// Allows usage of the `compile_error!` macro. (accepted, compile_error, "1.20.0", Some(40872)), /// Allows `impl Trait` in function return types. @@ -208,13 +208,13 @@ declare_features! ( /// Allows referencing `Self` and projections in impl-trait. (accepted, impl_trait_projections, "1.74.0", Some(103532)), /// Allows using imported `main` function - (accepted, imported_main, "CURRENT_RUSTC_VERSION", Some(28937)), + (accepted, imported_main, "1.79.0", Some(28937)), /// Allows using `a..=b` and `..=b` as inclusive range syntaxes. (accepted, inclusive_range_syntax, "1.26.0", Some(28237)), /// Allows inferring outlives requirements (RFC 2093). (accepted, infer_outlives_requirements, "1.30.0", Some(44493)), /// Allow anonymous constants from an inline `const` block - (accepted, inline_const, "CURRENT_RUSTC_VERSION", Some(76001)), + (accepted, inline_const, "1.79.0", Some(76001)), /// Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086). (accepted, irrefutable_let_patterns, "1.33.0", Some(44495)), /// Allows `#[instruction_set(_)]` attribute. @@ -360,7 +360,7 @@ declare_features! ( /// Allows macros to appear in the type position. (accepted, type_macros, "1.13.0", Some(27245)), /// Allows using type privacy lints (`private_interfaces`, `private_bounds`, `unnameable_types`). - (accepted, type_privacy_lints, "CURRENT_RUSTC_VERSION", Some(48054)), + (accepted, type_privacy_lints, "1.79.0", Some(48054)), /// Allows `const _: TYPE = VALUE`. (accepted, underscore_const_names, "1.37.0", Some(54912)), /// Allows `use path as _;` and `extern crate c as _;`. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 132e2ddee295..e7d7a9f380b1 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -216,7 +216,7 @@ declare_features! ( /// Set the maximum pattern complexity allowed (not limited by default). (internal, pattern_complexity, "1.78.0", None), /// Allows using pattern types. - (internal, pattern_types, "CURRENT_RUSTC_VERSION", Some(123646)), + (internal, pattern_types, "1.79.0", Some(123646)), /// Allows using `#[prelude_import]` on glob `use` items. (internal, prelude_import, "1.2.0", None), /// Used to identify crates that contain the profiler runtime. @@ -384,7 +384,7 @@ declare_features! ( /// Allows `cfg(target_thread_local)`. (unstable, cfg_target_thread_local, "1.7.0", Some(29594)), /// Allows the use of `#[cfg(ub_checks)` to check if UB checks are enabled. - (unstable, cfg_ub_checks, "CURRENT_RUSTC_VERSION", Some(123499)), + (unstable, cfg_ub_checks, "1.79.0", Some(123499)), /// Allow conditional compilation depending on rust version (unstable, cfg_version, "1.45.0", Some(64796)), /// Allows to use the `#[cfi_encoding = ""]` attribute. @@ -439,7 +439,7 @@ declare_features! ( /// Allows having using `suggestion` in the `#[deprecated]` attribute. (unstable, deprecated_suggestion, "1.61.0", Some(94785)), /// Allows deref patterns. - (incomplete, deref_patterns, "CURRENT_RUSTC_VERSION", Some(87121)), + (incomplete, deref_patterns, "1.79.0", Some(87121)), /// Controls errors in trait implementations. (unstable, do_not_recommend, "1.67.0", Some(51992)), /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`. @@ -530,9 +530,9 @@ declare_features! ( /// Allows the `#[must_not_suspend]` attribute. (unstable, must_not_suspend, "1.57.0", Some(83310)), /// Make `mut` not reset the binding mode on edition >= 2024. - (incomplete, mut_preserve_binding_mode_2024, "CURRENT_RUSTC_VERSION", Some(123076)), + (incomplete, mut_preserve_binding_mode_2024, "1.79.0", Some(123076)), /// Allows `mut ref` and `mut ref mut` identifier patterns. - (incomplete, mut_ref, "CURRENT_RUSTC_VERSION", Some(123076)), + (incomplete, mut_ref, "1.79.0", Some(123076)), /// Allows using `#[naked]` on functions. (unstable, naked_functions, "1.9.0", Some(90957)), /// Allows specifying the as-needed link modifier @@ -564,17 +564,17 @@ declare_features! ( /// Allows using `#[optimize(X)]`. (unstable, optimize_attribute, "1.34.0", Some(54882)), /// Allows postfix match `expr.match { ... }` - (unstable, postfix_match, "CURRENT_RUSTC_VERSION", Some(121618)), + (unstable, postfix_match, "1.79.0", Some(121618)), /// Allows `use<'a, 'b, A, B>` in `impl use<...> Trait` for precise capture of generic args. - (incomplete, precise_capturing, "CURRENT_RUSTC_VERSION", Some(123432)), + (incomplete, precise_capturing, "1.79.0", Some(123432)), /// Allows macro attributes on expressions, statements and non-inline modules. (unstable, proc_macro_hygiene, "1.30.0", Some(54727)), /// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions. (unstable, raw_ref_op, "1.41.0", Some(64490)), /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024. - (incomplete, ref_pat_eat_one_layer_2024, "CURRENT_RUSTC_VERSION", Some(123076)), + (incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)), /// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references. - (incomplete, ref_pat_everywhere, "CURRENT_RUSTC_VERSION", Some(123076)), + (incomplete, ref_pat_everywhere, "1.79.0", Some(123076)), /// Allows using the `#[register_tool]` attribute. (unstable, register_tool, "1.41.0", Some(66079)), /// Allows the `#[repr(i128)]` attribute for enums. diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index d88639c4092e..c0d292cd2088 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -53,7 +53,7 @@ pub use core::str::{RSplit, Split}; pub use core::str::{RSplitN, SplitN}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::str::{RSplitTerminator, SplitTerminator}; -#[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "utf8_chunks", since = "1.79.0")] pub use core::str::{Utf8Chunk, Utf8Chunks}; /// Note: `str` in `Concat` is not meaningful here. diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index f4f33f8584bd..aefb30463d33 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -528,7 +528,7 @@ impl CStr { #[inline] #[must_use] #[doc(alias("len", "strlen"))] - #[stable(feature = "cstr_count_bytes", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "cstr_count_bytes", since = "1.79.0")] #[rustc_const_unstable(feature = "const_cstr_from_ptr", issue = "113219")] pub const fn count_bytes(&self) -> usize { self.inner.len() - 1 diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 14b4ce39ab45..dc41fb5a7784 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1128,7 +1128,7 @@ extern "rust-intrinsic" { /// any safety invariants. /// /// Consider using [`core::panic::Location::caller`] instead. - #[rustc_const_stable(feature = "const_caller_location", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_caller_location", since = "1.79.0")] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn caller_location() -> &'static crate::panic::Location<'static>; @@ -2289,7 +2289,7 @@ extern "rust-intrinsic" { /// /// The stable counterpart of this intrinsic is `unchecked_add` on the various /// integer types, such as [`u16::unchecked_add`] and [`i64::unchecked_add`]. - #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")] #[rustc_nounwind] pub fn unchecked_add(x: T, y: T) -> T; @@ -2298,7 +2298,7 @@ extern "rust-intrinsic" { /// /// The stable counterpart of this intrinsic is `unchecked_sub` on the various /// integer types, such as [`u16::unchecked_sub`] and [`i64::unchecked_sub`]. - #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")] #[rustc_nounwind] pub fn unchecked_sub(x: T, y: T) -> T; @@ -2307,7 +2307,7 @@ extern "rust-intrinsic" { /// /// The stable counterpart of this intrinsic is `unchecked_mul` on the various /// integer types, such as [`u16::unchecked_mul`] and [`i64::unchecked_mul`]. - #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")] #[rustc_nounwind] pub fn unchecked_mul(x: T, y: T) -> T; diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 2ebbe2bf2743..563781230c02 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -169,7 +169,7 @@ pub trait FromIterator: Sized { /// assert_eq!(lengths, [1, 1, 3, 1]); /// # Ok(()) } /// ``` -#[stable(feature = "from_iterator_for_tuple", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "from_iterator_for_tuple", since = "1.79.0")] impl FromIterator<(AE, BE)> for (A, B) where A: Default + Extend, diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index a92da88dd3f5..f50419dad208 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -481,8 +481,8 @@ macro_rules! int_impl { /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked #[doc = concat!("[`checked_add`]: ", stringify!($SelfT), "::checked_add")] #[doc = concat!("[`wrapping_add`]: ", stringify!($SelfT), "::wrapping_add")] - #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unchecked_math", since = "1.79.0")] + #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] @@ -623,8 +623,8 @@ macro_rules! int_impl { /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked #[doc = concat!("[`checked_sub`]: ", stringify!($SelfT), "::checked_sub")] #[doc = concat!("[`wrapping_sub`]: ", stringify!($SelfT), "::wrapping_sub")] - #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unchecked_math", since = "1.79.0")] + #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] @@ -765,8 +765,8 @@ macro_rules! int_impl { /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked #[doc = concat!("[`checked_mul`]: ", stringify!($SelfT), "::checked_mul")] #[doc = concat!("[`wrapping_mul`]: ", stringify!($SelfT), "::wrapping_mul")] - #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unchecked_math", since = "1.79.0")] + #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 443401c5dba8..c02f73fdf036 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -67,7 +67,7 @@ pub use error::ParseIntError; )] pub use nonzero::ZeroablePrimitive; -#[stable(feature = "generic_nonzero", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "generic_nonzero", since = "1.79.0")] pub use nonzero::NonZero; #[stable(feature = "signed_nonzero", since = "1.34.0")] diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 5a0958fdc89f..fca367876593 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -109,7 +109,7 @@ impl_zeroable_primitive!( /// /// assert_eq!(size_of::>>(), size_of::()); /// ``` -#[stable(feature = "generic_nonzero", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "generic_nonzero", since = "1.79.0")] #[repr(transparent)] #[rustc_nonnull_optimization_guaranteed] #[rustc_diagnostic_item = "NonZero"] @@ -861,7 +861,7 @@ macro_rules! nonzero_integer_signedness_dependent_impls { } } - #[stable(feature = "nonzero_div_assign", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "nonzero_div_assign", since = "1.79.0")] impl DivAssign<$Ty> for $Int { /// This operation rounds towards zero, /// truncating any fractional part of the exact result, and cannot panic. @@ -884,7 +884,7 @@ macro_rules! nonzero_integer_signedness_dependent_impls { } } - #[stable(feature = "nonzero_div_assign", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "nonzero_div_assign", since = "1.79.0")] impl RemAssign<$Ty> for $Int { /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic. #[inline] diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index ea14d769cc19..bb5113577c22 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -503,8 +503,8 @@ macro_rules! uint_impl { /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked #[doc = concat!("[`checked_add`]: ", stringify!($SelfT), "::checked_add")] #[doc = concat!("[`wrapping_add`]: ", stringify!($SelfT), "::wrapping_add")] - #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unchecked_math", since = "1.79.0")] + #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] @@ -660,8 +660,8 @@ macro_rules! uint_impl { /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked #[doc = concat!("[`checked_sub`]: ", stringify!($SelfT), "::checked_sub")] #[doc = concat!("[`wrapping_sub`]: ", stringify!($SelfT), "::wrapping_sub")] - #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unchecked_math", since = "1.79.0")] + #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] @@ -746,8 +746,8 @@ macro_rules! uint_impl { /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked #[doc = concat!("[`checked_mul`]: ", stringify!($SelfT), "::checked_mul")] #[doc = concat!("[`wrapping_mul`]: ", stringify!($SelfT), "::wrapping_mul")] - #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "unchecked_math", since = "1.79.0")] + #[rustc_const_stable(feature = "unchecked_math", since = "1.79.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] diff --git a/library/core/src/panic/location.rs b/library/core/src/panic/location.rs index 4ad507d8b868..eb27da1724ec 100644 --- a/library/core/src/panic/location.rs +++ b/library/core/src/panic/location.rs @@ -81,7 +81,7 @@ impl<'a> Location<'a> { /// ``` #[must_use] #[stable(feature = "track_caller", since = "1.46.0")] - #[rustc_const_stable(feature = "const_caller_location", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_caller_location", since = "1.79.0")] #[track_caller] #[inline] pub const fn caller() -> &'static Location<'static> { @@ -123,7 +123,7 @@ impl<'a> Location<'a> { /// ``` #[must_use] #[stable(feature = "panic_hooks", since = "1.10.0")] - #[rustc_const_stable(feature = "const_location_fields", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_location_fields", since = "1.79.0")] #[inline] pub const fn file(&self) -> &str { self.file @@ -148,7 +148,7 @@ impl<'a> Location<'a> { /// ``` #[must_use] #[stable(feature = "panic_hooks", since = "1.10.0")] - #[rustc_const_stable(feature = "const_location_fields", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_location_fields", since = "1.79.0")] #[inline] pub const fn line(&self) -> u32 { self.line @@ -173,7 +173,7 @@ impl<'a> Location<'a> { /// ``` #[must_use] #[stable(feature = "panic_col", since = "1.25.0")] - #[rustc_const_stable(feature = "const_location_fields", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_location_fields", since = "1.79.0")] #[inline] pub const fn column(&self) -> u32 { self.col diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 9737fb8816e9..e9eeb3153307 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1496,7 +1496,7 @@ impl *const T { /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203 #[must_use] #[inline] - #[stable(feature = "pointer_is_aligned", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "pointer_is_aligned", since = "1.79.0")] #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")] pub const fn is_aligned(self) -> bool where @@ -1653,8 +1653,8 @@ impl *const [T] { /// assert_eq!(slice.len(), 3); /// ``` #[inline] - #[stable(feature = "slice_ptr_len", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "const_slice_ptr_len", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "slice_ptr_len", since = "1.79.0")] + #[rustc_const_stable(feature = "const_slice_ptr_len", since = "1.79.0")] #[rustc_allow_const_fn_unstable(ptr_metadata)] pub const fn len(self) -> usize { metadata(self) @@ -1671,8 +1671,8 @@ impl *const [T] { /// assert!(!slice.is_empty()); /// ``` #[inline(always)] - #[stable(feature = "slice_ptr_len", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "const_slice_ptr_len", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "slice_ptr_len", since = "1.79.0")] + #[rustc_const_stable(feature = "const_slice_ptr_len", since = "1.79.0")] pub const fn is_empty(self) -> bool { self.len() == 0 } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index d8f91f1996b9..c5a188dc7d4f 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1756,7 +1756,7 @@ impl *mut T { /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203 #[must_use] #[inline] - #[stable(feature = "pointer_is_aligned", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "pointer_is_aligned", since = "1.79.0")] #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")] pub const fn is_aligned(self) -> bool where @@ -1915,8 +1915,8 @@ impl *mut [T] { /// assert_eq!(slice.len(), 3); /// ``` #[inline(always)] - #[stable(feature = "slice_ptr_len", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "const_slice_ptr_len", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "slice_ptr_len", since = "1.79.0")] + #[rustc_const_stable(feature = "const_slice_ptr_len", since = "1.79.0")] #[rustc_allow_const_fn_unstable(ptr_metadata)] pub const fn len(self) -> usize { metadata(self) @@ -1933,8 +1933,8 @@ impl *mut [T] { /// assert!(!slice.is_empty()); /// ``` #[inline(always)] - #[stable(feature = "slice_ptr_len", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "const_slice_ptr_len", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "slice_ptr_len", since = "1.79.0")] + #[rustc_const_stable(feature = "const_slice_ptr_len", since = "1.79.0")] pub const fn is_empty(self) -> bool { self.len() == 0 } diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 8697b22278f8..617890cf083b 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1378,7 +1378,7 @@ impl NonNull { /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203 #[inline] #[must_use] - #[stable(feature = "pointer_is_aligned", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "pointer_is_aligned", since = "1.79.0")] #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")] pub const fn is_aligned(self) -> bool where @@ -1564,11 +1564,8 @@ impl NonNull<[T]> { /// let slice: NonNull<[i8]> = NonNull::slice_from_raw_parts(NonNull::dangling(), 3); /// assert!(!slice.is_empty()); /// ``` - #[stable(feature = "slice_ptr_is_empty_nonnull", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable( - feature = "const_slice_ptr_is_empty_nonnull", - since = "CURRENT_RUSTC_VERSION" - )] + #[stable(feature = "slice_ptr_is_empty_nonnull", since = "1.79.0")] + #[rustc_const_stable(feature = "const_slice_ptr_is_empty_nonnull", since = "1.79.0")] #[must_use] #[inline] pub const fn is_empty(self) -> bool { diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 6e1ba74f72b3..9c523fd6295d 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -1964,7 +1964,7 @@ impl [T] { /// assert_eq!(right, []); /// } /// ``` - #[stable(feature = "slice_split_at_unchecked", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "slice_split_at_unchecked", since = "1.79.0")] #[rustc_const_stable(feature = "const_slice_split_at_unchecked", since = "1.77.0")] #[inline] #[must_use] @@ -2017,7 +2017,7 @@ impl [T] { /// } /// assert_eq!(v, [1, 2, 3, 4, 5, 6]); /// ``` - #[stable(feature = "slice_split_at_unchecked", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "slice_split_at_unchecked", since = "1.79.0")] #[rustc_const_unstable(feature = "const_slice_split_at_mut", issue = "101804")] #[inline] #[must_use] diff --git a/library/core/src/str/lossy.rs b/library/core/src/str/lossy.rs index f8ecf1f3a7c5..51a0777c2d61 100644 --- a/library/core/src/str/lossy.rs +++ b/library/core/src/str/lossy.rs @@ -40,7 +40,7 @@ impl [u8] { /// assert_eq!(lit, expected); /// } /// ``` - #[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "utf8_chunks", since = "1.79.0")] pub fn utf8_chunks(&self) -> Utf8Chunks<'_> { Utf8Chunks { source: self } } @@ -66,7 +66,7 @@ impl [u8] { /// // The fourth character is broken /// assert_eq!(b"\xF1\x80", chunk.invalid()); /// ``` -#[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "utf8_chunks", since = "1.79.0")] #[derive(Clone, Debug, PartialEq, Eq)] pub struct Utf8Chunk<'a> { valid: &'a str, @@ -79,7 +79,7 @@ impl<'a> Utf8Chunk<'a> { /// This substring can be empty at the start of the string or between /// broken UTF-8 characters. #[must_use] - #[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "utf8_chunks", since = "1.79.0")] pub fn valid(&self) -> &'a str { self.valid } @@ -99,7 +99,7 @@ impl<'a> Utf8Chunk<'a> { /// [`valid`]: Self::valid /// [`U+FFFD REPLACEMENT CHARACTER`]: crate::char::REPLACEMENT_CHARACTER #[must_use] - #[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "utf8_chunks", since = "1.79.0")] pub fn invalid(&self) -> &'a [u8] { self.invalid } @@ -172,7 +172,7 @@ impl fmt::Debug for Debug<'_> { /// /// [`String::from_utf8_lossy`]: ../../std/string/struct.String.html#method.from_utf8_lossy #[must_use = "iterators are lazy and do nothing unless consumed"] -#[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "utf8_chunks", since = "1.79.0")] #[derive(Clone)] pub struct Utf8Chunks<'a> { source: &'a [u8], @@ -186,7 +186,7 @@ impl<'a> Utf8Chunks<'a> { } } -#[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "utf8_chunks", since = "1.79.0")] impl<'a> Iterator for Utf8Chunks<'a> { type Item = Utf8Chunk<'a>; @@ -285,10 +285,10 @@ impl<'a> Iterator for Utf8Chunks<'a> { } } -#[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "utf8_chunks", since = "1.79.0")] impl FusedIterator for Utf8Chunks<'_> {} -#[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "utf8_chunks", since = "1.79.0")] impl fmt::Debug for Utf8Chunks<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("Utf8Chunks").field("source", &self.debug()).finish() diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 3313da9dce78..adccbe02d46d 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -24,7 +24,7 @@ use crate::slice::{self, SliceIndex}; pub mod pattern; mod lossy; -#[stable(feature = "utf8_chunks", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "utf8_chunks", since = "1.79.0")] pub use lossy::{Utf8Chunk, Utf8Chunks}; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 073459fcb003..249b8ccb4374 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -579,7 +579,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "atomic_access", since = "1.15.0")] - #[rustc_const_stable(feature = "const_atomic_into_inner", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")] pub const fn into_inner(self) -> bool { self.v.primitive_into_inner() != 0 } @@ -1399,7 +1399,7 @@ impl AtomicPtr { /// ``` #[inline] #[stable(feature = "atomic_access", since = "1.15.0")] - #[rustc_const_stable(feature = "const_atomic_into_inner", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")] pub const fn into_inner(self) -> *mut T { self.p.primitive_into_inner() } @@ -2381,7 +2381,7 @@ macro_rules! atomic_int { /// ``` #[inline] #[$stable_access] - #[rustc_const_stable(feature = "const_atomic_into_inner", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")] pub const fn into_inner(self) -> $int_type { self.v.primitive_into_inner() } diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 1ceff2e506cc..23ae2e7dc0de 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -1360,7 +1360,7 @@ impl Literal { } /// Byte character literal. - #[stable(feature = "proc_macro_byte_character", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "proc_macro_byte_character", since = "1.79.0")] pub fn byte_character(byte: u8) -> Literal { let string = [byte].escape_ascii().to_string(); Literal::new(bridge::LitKind::Byte, &string, None) @@ -1374,7 +1374,7 @@ impl Literal { } /// C string literal. - #[stable(feature = "proc_macro_c_str_literals", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "proc_macro_c_str_literals", since = "1.79.0")] pub fn c_string(string: &CStr) -> Literal { let string = string.to_bytes().escape_ascii().to_string(); Literal::new(bridge::LitKind::CStr, &string, None) diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index 5b782fff7e52..f6680b211c7f 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -95,7 +95,7 @@ impl Cursor { /// # force_inference(&buff); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")] pub const fn new(inner: T) -> Cursor { Cursor { pos: 0, inner } } @@ -132,7 +132,7 @@ impl Cursor { /// let reference = buff.get_ref(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")] pub const fn get_ref(&self) -> &T { &self.inner } @@ -178,7 +178,7 @@ impl Cursor { /// assert_eq!(buff.position(), 1); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")] pub const fn position(&self) -> u64 { self.pos } diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 801621c6112e..f366cb8f42ba 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -921,7 +921,7 @@ impl Error { /// assert!(io_error.raw_os_error().is_none()); /// # } /// ``` - #[stable(feature = "io_error_downcast", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_downcast", since = "1.79.0")] pub fn downcast(self) -> result::Result where E: error::Error + Send + Sync + 'static, diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs index 266a447f06b5..b4c4dffc371c 100644 --- a/library/std/src/io/util.rs +++ b/library/std/src/io/util.rs @@ -51,7 +51,7 @@ pub struct Empty; /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")] pub const fn empty() -> Empty { Empty } @@ -173,7 +173,7 @@ pub struct Repeat { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")] pub const fn repeat(byte: u8) -> Repeat { Repeat { byte } } @@ -276,7 +276,7 @@ pub struct Sink; /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")] pub const fn sink() -> Sink { Sink } diff --git a/library/std/src/num.rs b/library/std/src/num.rs index fbe68f7e3038..8910cdea7c0c 100644 --- a/library/std/src/num.rs +++ b/library/std/src/num.rs @@ -23,7 +23,7 @@ pub use core::num::{FpCategory, ParseFloatError, ParseIntError, TryFromIntError} )] pub use core::num::ZeroablePrimitive; -#[stable(feature = "generic_nonzero", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "generic_nonzero", since = "1.79.0")] pub use core::num::NonZero; #[stable(feature = "signed_nonzero", since = "1.34.0")] diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 85355435100c..79d800ff0729 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -3374,7 +3374,7 @@ impl Error for StripPrefixError { /// /// [posix-semantics]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13 /// [windows-path]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfullpathnamew -#[stable(feature = "absolute_path", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "absolute_path", since = "1.79.0")] pub fn absolute>(path: P) -> io::Result { let path = path.as_ref(); if path.as_os_str().is_empty() { From 43f9a5ec0c70f149e1a44d791e199428e8e905fd Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 28 Apr 2024 10:10:32 -0400 Subject: [PATCH 222/279] Mark more entries in rustc_data_structures as no_inline for docs This is a workaround for #122758, but it's not clear why 1.79 requires a more extensive amount of no_inline than the previous release. Seems like there's something relatively subtle happening here. --- compiler/rustc_data_structures/src/sync.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index eab6d8168ca8..ecb85db33f70 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -46,6 +46,7 @@ use std::collections::HashMap; use std::hash::{BuildHasher, Hash}; mod lock; +#[doc(no_inline)] pub use lock::{Lock, LockGuard, Mode}; mod worker_local; @@ -199,10 +200,15 @@ cfg_match! { pub use std::rc::Rc as Lrc; pub use std::rc::Weak as Weak; + #[doc(no_inline)] pub use std::cell::Ref as ReadGuard; + #[doc(no_inline)] pub use std::cell::Ref as MappedReadGuard; + #[doc(no_inline)] pub use std::cell::RefMut as WriteGuard; + #[doc(no_inline)] pub use std::cell::RefMut as MappedWriteGuard; + #[doc(no_inline)] pub use std::cell::RefMut as MappedLockGuard; pub use std::cell::OnceCell as OnceLock; From 377c518bce25ebd2d1bf80568940787ffa397013 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 29 Apr 2024 09:17:40 -0400 Subject: [PATCH 223/279] Bump stage0 to next beta --- src/stage0.json | 848 ++++++++++++++++++++++++------------------------ 1 file changed, 428 insertions(+), 420 deletions(-) diff --git a/src/stage0.json b/src/stage0.json index a85fbf254fcf..a9a53a7528fe 100644 --- a/src/stage0.json +++ b/src/stage0.json @@ -18,431 +18,439 @@ "tool is executed." ], "compiler": { - "date": "2024-03-19", + "date": "2024-04-29", "version": "beta" }, "rustfmt": { - "date": "2024-03-19", + "date": "2024-04-29", "version": "nightly" }, "checksums_sha256": { - "dist/2024-03-19/cargo-beta-aarch64-apple-darwin.tar.gz": "d8aeeb8d427c346112020b84de85c1498d1ea043a01a45dd63d38da8ae0d35d1", - "dist/2024-03-19/cargo-beta-aarch64-apple-darwin.tar.xz": "f4c3aec8e916a93412c6c798c43dab1dd64c0095509a2a255191751a230730ad", - "dist/2024-03-19/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "d6161a55f808b6d54a061f9ffd9c33489b844f450f07a40e2f6cdb7def75792b", - "dist/2024-03-19/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "cba6e510866f9d920ee40e66069e8d152c0bfdabcc280ba0175a103460614839", - "dist/2024-03-19/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "e99299705d9b596554a4156ca7e8cd1bab95d926b519fd79e24d7b4c00bf4bbe", - "dist/2024-03-19/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "d006ecc2215a0b7b1d3040c64d72094589bfe11f1ffd34f63e5aaa8fb52ee4b2", - "dist/2024-03-19/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "9f6b9bd599948b48085bf592630963a5b69608abff67dd3674327d7efdcbf695", - "dist/2024-03-19/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "e3bd8ad798b098f1e03333bece43fe163f4d4b613bf38de4809106ca98b99c05", - "dist/2024-03-19/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "5ec13385ad03d14fa8fd48fd3f92df123a1626bb8a594df33c0bdee02d5a811c", - "dist/2024-03-19/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "bf201ad295272ee9435da1afcd4888c31bb14e467edb9638fdfe95b071bc869d", - "dist/2024-03-19/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "0e09177180c2822378bdb66dca69fb8bc7e7d5c51f414bdd95b9497c683d466f", - "dist/2024-03-19/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "5815c1421d474d8cd238fff80db5ba5231155abbd8642eeced84842d34f49ba9", - "dist/2024-03-19/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "36967ecac443fdcace710bae63eedcf65a4c2015793ed30ea3edae3d93f24707", - "dist/2024-03-19/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "1932898203f99c2aee95e71226c66b48d8dcbe40aa3a8b0782856fedcd291b13", - "dist/2024-03-19/cargo-beta-i686-pc-windows-gnu.tar.gz": "948157661b4b54b4c963933d97d4721efb6c8134242b96a82b86ee4be8dfe043", - "dist/2024-03-19/cargo-beta-i686-pc-windows-gnu.tar.xz": "26afbb06b1a47945172cee64470803670d1e41529f4e0f357f48633565efc489", - "dist/2024-03-19/cargo-beta-i686-pc-windows-msvc.tar.gz": "82e81f26ba6a207ac891a13bd9eb58c2cc33d31e78d354a210c4518b2d2b4dfd", - "dist/2024-03-19/cargo-beta-i686-pc-windows-msvc.tar.xz": "2b697674c4535bb58910dea6fdb9948a3b06ecdb723a638c01558615cbbf3fb0", - "dist/2024-03-19/cargo-beta-i686-unknown-linux-gnu.tar.gz": "2273118fc50fe605d53b078b5859d2694555f6c9ce2a61478f5af1765cffb997", - "dist/2024-03-19/cargo-beta-i686-unknown-linux-gnu.tar.xz": "53ae185d70ead1a251aac0793cbc784858d7a666530cacb63404541bef2a8bbd", - "dist/2024-03-19/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz": "f37429c8406938888600b180b60db99a5343866e8ba6c595350c60a631d6cc2e", - "dist/2024-03-19/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz": "ca49cac7f00c94ab5ac936c500a96092fc44a2cf9f1e10d52aa877ad9a57c548", - "dist/2024-03-19/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "262a48b6cfe9ebc8e19847e5ffa22459398395a9f9c9bb0891bf7b247b9d800a", - "dist/2024-03-19/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "6300c528f7457e0349eb2ff25e24122e5448855a4f05f265b810b328d4310516", - "dist/2024-03-19/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "e0dd3b037664c468eee9340235454b0a01310eae6025d5e2fb142027ff079cd5", - "dist/2024-03-19/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "36de5c67fdbc1eacdf00a51e2b44df5c1ee50ecd83755e893b6cb41bf49f30b5", - "dist/2024-03-19/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "cb5cdabb2d9d0398895b491f3cd128bd16488464fb3b8bc24f8e2e115154bbbf", - "dist/2024-03-19/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "e597718951b6f2973a68d587b84b6d4ce51e180e74b1060fdcbc3cfd05e04291", - "dist/2024-03-19/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "0a860fccb3f7ca44ca94ed76b1b81a2033e9c6806b32b428b49794508529e5be", - "dist/2024-03-19/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "10eaa329dc9a40337df22edd21a7396fd87852afcd0e68f1334cb374a56aa5bf", - "dist/2024-03-19/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "2f511c9d6ba6b489d96f531778af89baa3cce98ddc2e015198a0fbda95c0077a", - "dist/2024-03-19/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "d510515fa11961e56c05a946fb7200ce42b3831280177fda78260915f9b0192f", - "dist/2024-03-19/cargo-beta-x86_64-apple-darwin.tar.gz": "e4d542ce10c993bbdd1103d605c5c15771629750f204c5de76af93b0f0278391", - "dist/2024-03-19/cargo-beta-x86_64-apple-darwin.tar.xz": "36ff8a7806bd8bcb2c0054f994ec32bc5b30907c3ea2dd3cd07a440b6ee031c3", - "dist/2024-03-19/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "d3daaa2be8f7b761c37cfca9a1a242e2b0231795e1cb868246ed1e379c3969d8", - "dist/2024-03-19/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "1cda9d7c448336878071e6eb27338bd0346ec5ea28a8d29a6dcb3caa9b96fc54", - "dist/2024-03-19/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "cd1539eca02777df1ff8bf70d4f4abe59ea3a2d1cc625fb714b941502f863198", - "dist/2024-03-19/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "e97a05c1ba1a4aec2d424845b0b874712f15568c2e9cd61222663b96b759bb3f", - "dist/2024-03-19/cargo-beta-x86_64-unknown-freebsd.tar.gz": "aa2de3a607bc0fd4b4f99b2a6c8c024a75823d7ebea553748d24ad2841f3c919", - "dist/2024-03-19/cargo-beta-x86_64-unknown-freebsd.tar.xz": "6546733a7b4a34b5739b9a1d1cfac8eb7ae320a14a242e8298564e33b2b4208e", - "dist/2024-03-19/cargo-beta-x86_64-unknown-illumos.tar.gz": "e48ad6cfa052ee84226e79cd037b4ff02d6974139225a69edac26db10f894c12", - "dist/2024-03-19/cargo-beta-x86_64-unknown-illumos.tar.xz": "2a55ac5d8aecb87d7625a90a5f1560859f516a44825b189b7d0cbbe0de787bd6", - "dist/2024-03-19/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "19db36d6b51c3e16869fc4be4133e321b103211fa8fd7a072dfb8dfa5dd108b6", - "dist/2024-03-19/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "97a90f062125ed14fc9723ecf3e68e12fc5853efb83e0afeef97dadd1b0e032f", - "dist/2024-03-19/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "231529bb7dbefbdba9b741a03ed210963966e217b684b05bfe8ff61af46577c9", - "dist/2024-03-19/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "b5e82d094176f729dc500d67ef5f4102df558718020f43536155ac4a74d6a01b", - "dist/2024-03-19/cargo-beta-x86_64-unknown-netbsd.tar.gz": "c6b836aa6f7cd086a7316fbcaf9e3de080d310db60eacc0910a3b90bbf5c224e", - "dist/2024-03-19/cargo-beta-x86_64-unknown-netbsd.tar.xz": "dcb398fb25568a0e5374be22be14f8dc1c0a7221fc5e60dc9258d4767f774058", - "dist/2024-03-19/clippy-beta-aarch64-apple-darwin.tar.gz": "7f4cf1177f0f22f471b8bf219d13b59b626089b3c2a563b3559dc66a573c8375", - "dist/2024-03-19/clippy-beta-aarch64-apple-darwin.tar.xz": "78d5efca461180bfdcde7e4672ac06221a0809386624b4f6892e0037df8be572", - "dist/2024-03-19/clippy-beta-aarch64-pc-windows-msvc.tar.gz": "8d3443465b4f0cbd6ba7e5bd8614071ce826798f80d7c6e35cc71ef463675952", - "dist/2024-03-19/clippy-beta-aarch64-pc-windows-msvc.tar.xz": "4ea23f92b8f36a271c36df93008a00e0a0519dfdc0da69cc920f7edf317b4ae9", - "dist/2024-03-19/clippy-beta-aarch64-unknown-linux-gnu.tar.gz": "1eabd5f5bce761972022f52dc86cd408f7106a7df2a0d9b1701afc1bcb39ed39", - "dist/2024-03-19/clippy-beta-aarch64-unknown-linux-gnu.tar.xz": "05feb29e8c526ed85e331f091b046767c4a01d68129c6a873536703dee529323", - "dist/2024-03-19/clippy-beta-aarch64-unknown-linux-musl.tar.gz": "c023d628e7d23ad3d94791e595b0ce4033c24b5e53f806947b88a6cddd93e1b8", - "dist/2024-03-19/clippy-beta-aarch64-unknown-linux-musl.tar.xz": "96b29dba180d5bf4caa40b5c8538248b0b820991d91eab819b2ce0fe093640b9", - "dist/2024-03-19/clippy-beta-arm-unknown-linux-gnueabi.tar.gz": "5d9a8237c5d2258e7ff18cee7cad2308e6ce3935251c8fb74932ed84b1e23a52", - "dist/2024-03-19/clippy-beta-arm-unknown-linux-gnueabi.tar.xz": "625f0415d85c08281efb4cdd6d362636876360774297487ed92337e72058c896", - "dist/2024-03-19/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz": "5d9e03efe64eb1a60dfa011b1641a74979295cf6540e081672deed82fd130132", - "dist/2024-03-19/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz": "e9bed26481e7678e7e4388c0e6885ab323b9cecc270a3044b08cb681eed5333d", - "dist/2024-03-19/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz": "26e0a630657c7abe765132bfab93aa39013ff19aec1978e41968cb53e6c46693", - "dist/2024-03-19/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz": "30abee9b263f4ff6f7e696a41f5356957daae5953c224fcd1f253ce41dcd94ea", - "dist/2024-03-19/clippy-beta-i686-pc-windows-gnu.tar.gz": "845732a863b79922ed5057ddf7c911bae71381082bdcf68799c8f79c0f48d192", - "dist/2024-03-19/clippy-beta-i686-pc-windows-gnu.tar.xz": "75f1abca075af64656d176ac1ea37e24c000378f1750a708924b44fdc223c389", - "dist/2024-03-19/clippy-beta-i686-pc-windows-msvc.tar.gz": "e5a7d0ff6d1f8d9bfeaab8f8aaf1c18528c1eb447169454c965838a2b836c201", - "dist/2024-03-19/clippy-beta-i686-pc-windows-msvc.tar.xz": "ad5a7313ca6fbd8051c0db761bbae67d3405cc5a98ec20891f26c15b31b5b2b0", - "dist/2024-03-19/clippy-beta-i686-unknown-linux-gnu.tar.gz": "cf67172fcc26b9b45138f0ac12721c1fe226a892346145b4a0ff1931d60fb756", - "dist/2024-03-19/clippy-beta-i686-unknown-linux-gnu.tar.xz": "3adb4d8a782a80d85f4cdfc433f63656449a06dddc67f0b11bf399d9a8aae97a", - "dist/2024-03-19/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz": "175d58f41d0b08bc1ac733bee1d16db31a4a64f7703a87ea1f13ec72b19be4d7", - "dist/2024-03-19/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz": "73925325e092d84ba3a8aff695953142962221fecaab9d57dc61b4d03338bb12", - "dist/2024-03-19/clippy-beta-powerpc-unknown-linux-gnu.tar.gz": "cec90ecbdfd252e49de68fa69806f5662bd4f4ab093708104e19b228564c0ee4", - "dist/2024-03-19/clippy-beta-powerpc-unknown-linux-gnu.tar.xz": "eb085114c178c8e16ec77657fb658b537eff1125f3de5d7e07f1ccd62e8b834e", - "dist/2024-03-19/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz": "b599d42a4100a7b1304eee34571abe1e6e38e873f8197e46d0d4d92dbb0ccd27", - "dist/2024-03-19/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz": "57338b860b283cfed3cf1eb38083113f026cfc91135e439b75de1a3acc9e42b3", - "dist/2024-03-19/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz": "00f756d858949ad83ad32dca5c5a93cd283da3c91f4976564afd5be3b4f5927b", - "dist/2024-03-19/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz": "4a8d250c30312dfd4f8d259ca4376555bbc6cf290a884aff92e6b06a852acf6d", - "dist/2024-03-19/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz": "992a77181709bf235c1e0a335a82b0ee01fe8f749956f2aad52a386685aeae6b", - "dist/2024-03-19/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz": "b523cf81d4ffbcc0bb9f4f5805eeb39624901eea591c852f9594690350848c54", - "dist/2024-03-19/clippy-beta-s390x-unknown-linux-gnu.tar.gz": "5f22463a8c138fb3934a405bc0f7de4b5ea51c86b75f7739eccd7181fbeb4e9a", - "dist/2024-03-19/clippy-beta-s390x-unknown-linux-gnu.tar.xz": "2b507322b80e562a0dfaba16210a2f1d65051a740869ce5a952bf83a9099e0f2", - "dist/2024-03-19/clippy-beta-x86_64-apple-darwin.tar.gz": "6873e1a437b6783e349d4fe1cd69f996f579b623c231d55933ec194de19d0a15", - "dist/2024-03-19/clippy-beta-x86_64-apple-darwin.tar.xz": "4b8f43b267b25bc5f60541fe6b98254c2731f0ee55129cc132e28c4f3b2bbc24", - "dist/2024-03-19/clippy-beta-x86_64-pc-windows-gnu.tar.gz": "e697e4c34422519db58b44bf8ed164fc45dadf4ac114c3e662f6990d4d9a5522", - "dist/2024-03-19/clippy-beta-x86_64-pc-windows-gnu.tar.xz": "5ffd1038684dc68bf97f9a74c08beca4c3eb66b39b11e32e7da45b763fe1f7f2", - "dist/2024-03-19/clippy-beta-x86_64-pc-windows-msvc.tar.gz": "7e334464dbbe5be014de9ef6872a1b2066016204e7ae8c11e55fbf64bedb93da", - "dist/2024-03-19/clippy-beta-x86_64-pc-windows-msvc.tar.xz": "55b4aaa0a64d9e3cc2489a678935277d91b1f8223186c52b59bd33dbd403d52a", - "dist/2024-03-19/clippy-beta-x86_64-unknown-freebsd.tar.gz": "6fa2e2bdd09242ab44ad35853cf9493ad57d602536406ecd3504db5af87b827a", - "dist/2024-03-19/clippy-beta-x86_64-unknown-freebsd.tar.xz": "b1b79f8130d61c92d3d101a4d24416ef37fd446f18de0745be2c1fed7b276b57", - "dist/2024-03-19/clippy-beta-x86_64-unknown-illumos.tar.gz": "ee1af20cc23288fecf8ebe33e877e1de3184711a38ea378a6f4da158919b4059", - "dist/2024-03-19/clippy-beta-x86_64-unknown-illumos.tar.xz": "af724f142b19b7436547a5eb2b2b40d1acf959a73feca03efd9178948af9326a", - "dist/2024-03-19/clippy-beta-x86_64-unknown-linux-gnu.tar.gz": "376cf1787e41ba9d231191f6cae260895be18c3ececc2f2e934e850de7f1cbda", - "dist/2024-03-19/clippy-beta-x86_64-unknown-linux-gnu.tar.xz": "8d7af83d3594a151564f351eed4cdfd1c7eb5b07e073e12c6d7b7ef9ad597007", - "dist/2024-03-19/clippy-beta-x86_64-unknown-linux-musl.tar.gz": "218168e4817f70f65651f3b9561ba8e8dd3e0d8c8a33a88ba9ad0a4a501468bd", - "dist/2024-03-19/clippy-beta-x86_64-unknown-linux-musl.tar.xz": "f55143ece3326ac8c004b77e59c1a60a70b3f1189c7e2e442183097f1cf639c2", - "dist/2024-03-19/clippy-beta-x86_64-unknown-netbsd.tar.gz": "9a5c08d2e00d2f38de5a9882fe7dcadd6307a333b8caf5826687301f8d97d09a", - "dist/2024-03-19/clippy-beta-x86_64-unknown-netbsd.tar.xz": "7be02599b4c2cd26365075ebfbb1534f6875d85501fe5a300895506e41ad0824", - "dist/2024-03-19/rust-std-beta-aarch64-apple-darwin.tar.gz": "7238015aa0e8553b6e820483e15f08119fa0b6c074abe127be99fa990f132c8f", - "dist/2024-03-19/rust-std-beta-aarch64-apple-darwin.tar.xz": "0dc783f3865ddf6512721abcd9c668f6d8533c3581015cfd4740b40cb09ce199", - "dist/2024-03-19/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "90541bf8f4c1fb838fff2620b55addee59687b16d3f10f92b59a41936ffa143d", - "dist/2024-03-19/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "b0d14d73d404197994e41deb2d92049ec043c875a81dda52c4e4fc64e53c8065", - "dist/2024-03-19/rust-std-beta-aarch64-apple-ios.tar.gz": "3105f19fd78bcdc5171cf4041aca9da236150e43ef9c32ee1163aafbc79d311f", - "dist/2024-03-19/rust-std-beta-aarch64-apple-ios.tar.xz": "13629cec9404312c6b42fd7aac14edc5eee98947be5152ae5708db899d2ebb4e", - "dist/2024-03-19/rust-std-beta-aarch64-linux-android.tar.gz": "3fb671809fafdabcb4cd8ea6c00caf3cfa2da3421770c08abf761456f079c425", - "dist/2024-03-19/rust-std-beta-aarch64-linux-android.tar.xz": "8f8f22bd89a29db1a549414440da19f3100abb689fb095c3e09ef28a223ee3cd", - "dist/2024-03-19/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "2326cc5061a6acc3cfea5a0e2ea965e07a0103052cfb4435e5dc947573b62e11", - "dist/2024-03-19/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "87327aa9f683ef9f574348cc0ec58b0f88fdcd6563d51b69664b3588897783ca", - "dist/2024-03-19/rust-std-beta-aarch64-unknown-fuchsia.tar.gz": "5f589736703a21a17366dd93c36ee6f597a40999ce6c305ff1e007918fe6aaef", - "dist/2024-03-19/rust-std-beta-aarch64-unknown-fuchsia.tar.xz": "65386ce4aa697b74c463e1c8d793ded996f6dbf1327242aaf61471968212c1e7", - "dist/2024-03-19/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "590b12f5fdf32251c1e0ad2af619b70b73a888d3a33a705f023b81369bcbbfa8", - "dist/2024-03-19/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "c22e0e88e1fd0041c95317bbc0e39e7d4e4e6a8d73eedc141628ec9e41d844f5", - "dist/2024-03-19/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "7e8e04e2bd58ac03c5dcf017562d3ad92993896a5f5a31e199990685adb206b7", - "dist/2024-03-19/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "8d0c5b70230122904e36731290f62dcf24fca2390d4c892aeb9b8f241d380563", - "dist/2024-03-19/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz": "89d476e9654dce23fb77cef86831813d143435e4e1a9547936f5eabb9a7e649b", - "dist/2024-03-19/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz": "b1b5c25e682961301e60f115eba6177a1be97b3157a0671c0ec64563765ddfdd", - "dist/2024-03-19/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "e8b2b4cd75800e5cd5b8f5ad97d6ef9fef8e6a7852a227406e89a3f7f50d33d2", - "dist/2024-03-19/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "e5c603df1515777eb1af5c9532194fde8ea3554abfefb93499025a9a98fdc182", - "dist/2024-03-19/rust-std-beta-aarch64-unknown-none.tar.gz": "55605666a2bde23365937c811899f9e61855a28668d4b050834b83f5af8b03b5", - "dist/2024-03-19/rust-std-beta-aarch64-unknown-none.tar.xz": "f68fa43e4ee4d86b7bba6c316efba5ef6e3d500b0659ba4a0295df814beca459", - "dist/2024-03-19/rust-std-beta-aarch64-unknown-uefi.tar.gz": "5b9dbe42c686670836ba26acab3afa218fa70b616d3a7951298ce5cf2eff88bd", - "dist/2024-03-19/rust-std-beta-aarch64-unknown-uefi.tar.xz": "fcc8316db3cef3a3c3240a490d18162cf724fceecb595a0c40067c6a20a53caf", - "dist/2024-03-19/rust-std-beta-arm-linux-androideabi.tar.gz": "abdd4c98992cf2f9a9a558c5c74283826de3bb48d7743e67ef1f9d1dbc40f534", - "dist/2024-03-19/rust-std-beta-arm-linux-androideabi.tar.xz": "c597c457071b82c8842958c6ad383db30741952b06b40f138a5bed3bbca62c70", - "dist/2024-03-19/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "2a11714a2e5d18f7f255feece850a4c8ab7e1b14f6eb116c47eb972825abfdc2", - "dist/2024-03-19/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "5a6f054ebf50bf4bb196a32019276bed1cbcb74cbd3d46877a48ed77c09638c9", - "dist/2024-03-19/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "422d4d3a2f32a1739d18c208e89e5c490ce9b85c771726b21d265cb7632ffd49", - "dist/2024-03-19/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "d9fb3be5b4d577a469f4dc9cce5e4631741d6661a994d15cc1db847ab4edcaed", - "dist/2024-03-19/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "6a9c25b659a7d16f01148144883e47bddb29e2d79f7b590f58efd4b002abe38e", - "dist/2024-03-19/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "2c797105730a6a2a9d8ec5506f2028d42aef48d7ae09fad11e1ef3a0dc3c9a81", - "dist/2024-03-19/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "4f58e423159b7b5a8d546c288572dc644e73cfd5e22eb87f98670e1bdd4cfb42", - "dist/2024-03-19/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "d549997c4be8efe2feee163096b370ca6ddb0884dbf82af0c1d08e5f652a3b26", - "dist/2024-03-19/rust-std-beta-armebv7r-none-eabi.tar.gz": "2e199f5246edf22faf1b8876bec5290a7a111a38cffb831fedef3f4d4e57dded", - "dist/2024-03-19/rust-std-beta-armebv7r-none-eabi.tar.xz": "ffc4118d0520df6d4101c05c4df31bdbe91ce302b37d9d41e3dfdfd8fcb5b49a", - "dist/2024-03-19/rust-std-beta-armebv7r-none-eabihf.tar.gz": "39e2a7464ef3e48104873f59b6198cad8333835a0fe46805b00f2a3a8f1989aa", - "dist/2024-03-19/rust-std-beta-armebv7r-none-eabihf.tar.xz": "ff22a6f9b7c7873fe84943bbcffabba04e2632166ce63e405056ca0ee8fcdb62", - "dist/2024-03-19/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "51128c12bcd8935bed76a555da1e403e1b374155278ed957d078a2c887512a15", - "dist/2024-03-19/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "5370c2da10bc8efe00f0840d8ea6f664d38518288ed402a4ac164ae71cf1dfe9", - "dist/2024-03-19/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "ba104dbdcc3c8689dadb75c6a85d83419e32fe78f43039f5294020da2ab3b73a", - "dist/2024-03-19/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "7bb849dae31f472febd722dc7dd324f073b2739dc57c40a6590b10f61c26133e", - "dist/2024-03-19/rust-std-beta-armv7-linux-androideabi.tar.gz": "c44211a45a1ecb9b5800fb7a3b7fa88de4562845888588012b34e282e26cb4f8", - "dist/2024-03-19/rust-std-beta-armv7-linux-androideabi.tar.xz": "3a92cdd368559d06d290af58fda93eac98e6d4bfd4e6ad03db0f91fe01789504", - "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "f00db0fd04a921cebe68a21d3c923e44f8a1828cdfffa201826d333feb0b9bd6", - "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "af5ec7e114c8558080b8891269cca098b530809085577485ea96435d5f664e4b", - "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "5b2aa8f0c2a005a5c98dd08a6d4d231a11992356f857b706a19cefa66d62dc9a", - "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "7ab1a7cda6ae70836df20a70283af166ad2d5413755485d818d8760f3bf69f6c", - "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "9b970f2b3e0a01ecf56a9d32cdfbc47d76a2518838bc231d4488c2f4a9426fa7", - "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "934272fbb78cd09728ef03557fad7e2b1b9302f88579dee8a5a1f58c8f4b15bd", - "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "f70a1adf38b2d22b1706af807023154b626f656efb8d91c8ed7235bfe0855edf", - "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "a665e05bb8dff2e8dd0479cb8a63460c73ee3e86ec7e1b6f48fece2985c85e52", - "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-ohos.tar.gz": "e0ec71714bceee0df1bcdb85e094b58359d41f273dc9abab7ac05346fcd3f4b9", - "dist/2024-03-19/rust-std-beta-armv7-unknown-linux-ohos.tar.xz": "afbcd9b7ecc92f69801d77185af0139136ba6c352d14a6c8ed76de64a87645f5", - "dist/2024-03-19/rust-std-beta-armv7a-none-eabi.tar.gz": "a0e55f17c1bab81bf836c1e373f77d25c42fbd05f04b8b0e96f66f1f744481d2", - "dist/2024-03-19/rust-std-beta-armv7a-none-eabi.tar.xz": "f2dd0221e76d7b9f51e9efdee2e40c8d7539b1d5f52257f89431f29931394510", - "dist/2024-03-19/rust-std-beta-armv7r-none-eabi.tar.gz": "e97324f421bb354bc841a20e8b1c0357e633595bec4fca510f06e56fb89b2a6a", - "dist/2024-03-19/rust-std-beta-armv7r-none-eabi.tar.xz": "1ce1ca60b9536ede90452621ba91539b8ca6b6bdf7cbda3bd6d0b04a28c09580", - "dist/2024-03-19/rust-std-beta-armv7r-none-eabihf.tar.gz": "9bffa04e8cd3f67d8892f851b269f9cd91f6c9e5f2c87c641e9f6ef24bf7b644", - "dist/2024-03-19/rust-std-beta-armv7r-none-eabihf.tar.xz": "2a3cd2ab92cc37698057629167a553d0654f7882bfc1eb46687e1014b4b8e379", - "dist/2024-03-19/rust-std-beta-i586-pc-windows-msvc.tar.gz": "284f13947d990587090beb32262e4a83089c56ce2c3a1ffb89ed0fc5f4661eb3", - "dist/2024-03-19/rust-std-beta-i586-pc-windows-msvc.tar.xz": "22e641bdd54b3a7030c2eda0ff20a5517607fb6e60ea6d3195a2cd3afb0e984a", - "dist/2024-03-19/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "adaaf6d3a291640ddaa3d522d8331cb27ea899999681d57713b57c879b55de96", - "dist/2024-03-19/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "ebe80c2420c0eedd219cd539b87de75ffc0ed3b1656284cb81e2b2e8a927c738", - "dist/2024-03-19/rust-std-beta-i586-unknown-linux-musl.tar.gz": "c2e4691bf6956f97a214ef80f015a77ec4ece4ee32e9bc73300fe1c0267dcabe", - "dist/2024-03-19/rust-std-beta-i586-unknown-linux-musl.tar.xz": "e67059e579532ceb06a46702cc561acbeb3ba6258eda47418da587ec45759e26", - "dist/2024-03-19/rust-std-beta-i686-linux-android.tar.gz": "f112053adbcce7710383afe1681bd0096444a516f78f576e29f2f3c76468e7f0", - "dist/2024-03-19/rust-std-beta-i686-linux-android.tar.xz": "e63ae04fc20519fb5a56c2bae49f767807cb1ae1c01cab34dee1d129b34c4dee", - "dist/2024-03-19/rust-std-beta-i686-pc-windows-gnu.tar.gz": "14b36d2952ebaa84bf24645cd5d3464ae2b9df4d3ffee4bd48fedb07a4fdb09d", - "dist/2024-03-19/rust-std-beta-i686-pc-windows-gnu.tar.xz": "fef8c1bd4e1ceab680e1856b35f4ed426d07c224fa60c92d12efe0dfe700abc9", - "dist/2024-03-19/rust-std-beta-i686-pc-windows-msvc.tar.gz": "b42794fb8feda98c99d36dd978373afbfab56fd374fe42318107c453ab4d0fb7", - "dist/2024-03-19/rust-std-beta-i686-pc-windows-msvc.tar.xz": "855ed5996d9d8e4bc2424ce5ea6da6155b23357d700f1fc07d69d0bd12672a8f", - "dist/2024-03-19/rust-std-beta-i686-unknown-freebsd.tar.gz": "0ac04b35b62c7d8fe42ee29854b6a40b7dcf0d3deb174031a7620d2c87a8b206", - "dist/2024-03-19/rust-std-beta-i686-unknown-freebsd.tar.xz": "0287daaa3042c644d3190c6262b60b580a0cdfd80c64c299a36e0636d38e5674", - "dist/2024-03-19/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "647dd5ba2f4d842d6bd6377e99b67b3d65d3ee47ea800ace9d172e9d24f63eb0", - "dist/2024-03-19/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "d705b0cce3492e863c5d8fb28b4f2bedce68637fd7093d24a9e86ff6d2d0ca56", - "dist/2024-03-19/rust-std-beta-i686-unknown-linux-musl.tar.gz": "561ca95399cbd2f6692e5194ab550e9e0f0f5016aa2802522131c1361d3ef467", - "dist/2024-03-19/rust-std-beta-i686-unknown-linux-musl.tar.xz": "d4751c26585e512211157e162f0d1504a1854249dd6eff7262a55b09834d29fd", - "dist/2024-03-19/rust-std-beta-i686-unknown-uefi.tar.gz": "4e0a84f3dbc742d589d35cd58980157072f17090472c31ed0e306dad049a75ec", - "dist/2024-03-19/rust-std-beta-i686-unknown-uefi.tar.xz": "e11820072ae90861c96b0c1c931d691a157cccbf5d44685e3d5ff9b075aa7500", - "dist/2024-03-19/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz": "4357b6646ed0f379d9d74358457db1a18289967a880567b9bbff480e72f13711", - "dist/2024-03-19/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz": "3ffb178cb4c24b3b6df4aacbfaa4280eb6e781cd471fe52ed0b9be8fa555617b", - "dist/2024-03-19/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz": "bc32e2189cfb3efd8365bcd31fad504cab0fdf62c9fe04a6a0389ff23486cc2b", - "dist/2024-03-19/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz": "0d2894fe5fa5360cb31e5267e980faddd8d9f7adc415747991381aae535210eb", - "dist/2024-03-19/rust-std-beta-loongarch64-unknown-none.tar.gz": "16c134291f43694fb92d3efd92abc9c957d3ffa8ba8dee0c792d77f3b4d2cdd7", - "dist/2024-03-19/rust-std-beta-loongarch64-unknown-none.tar.xz": "ca06f72e2bd7309831464152cc7532a27406c18e2d6cd02918109aa65896be1e", - "dist/2024-03-19/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "a2d4f9671514673abc87ade8237508bd41df1bb6b75b0ea92bb27dd7ab75303e", - "dist/2024-03-19/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "69a8f2751d0a86878b92bb052ca0d3394f5bc0545fd3f2c1ce7e03e1ecc6d0b5", - "dist/2024-03-19/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "95c4f0f944b4b8ad08c4d0350a09be233796991b8790fc0d48dbae895953d73d", - "dist/2024-03-19/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "8ae7b77e0c7be184f4f279365eb2d9b7e9182ec9ea10f987814d4f4b50937f95", - "dist/2024-03-19/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "4f886546746f227bff157959a9982529895d52737b6137bf44545e82fe522672", - "dist/2024-03-19/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "b9fd4eda7aa2d5eb70e47405ba5fac8d5d3d15d1de76bb5d2f9d0ba8da4a2115", - "dist/2024-03-19/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "8e81b39b1d7cbc180fe9540e9420f68216aa9b3bd46d6cc6f758f473d8d54ae7", - "dist/2024-03-19/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "29d4e64b6e2a326bb695e42354e4f8a21382c63cd8a93fae64a44f3398de0a96", - "dist/2024-03-19/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "66eb8d049d50532512d442efef67993fa3da0fc0a585e549559d2e843c7e3c89", - "dist/2024-03-19/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "1919690c47b603ff6ddcf6d8f16573cc3acd960d27dfb97358dd9c92a907c766", - "dist/2024-03-19/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "e66c025f225b3cfc3399992b0dc3e5f6829ef03b6527656376a0575c970dd43a", - "dist/2024-03-19/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "75373475011adc1d3340dcf222e594be505116fa4c1099b493a6eb1018dc5f92", - "dist/2024-03-19/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz": "2dc076319958052445c0de0d34567162745d9a6de18edff2edbf6afa05feb124", - "dist/2024-03-19/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz": "f1225e56a378ac5b8790e9299815987c618f5d712a11e2a039580965679119a1", - "dist/2024-03-19/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "26bb1e505811310fecd47e7aa5b75cbbaf6794ce209df200ac554ff84a353392", - "dist/2024-03-19/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "35b4799e26da0d6220c0372bce45e6b3b18a4035b82a36505c052e0990cba754", - "dist/2024-03-19/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "5a79d8992906ab3db7be9716de2c6434e1c8d81c1ebf725a1b413af13f9c9091", - "dist/2024-03-19/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "7d63304af691b1ade5f9d6e50bf82eb9958f8b3da977fbf894f3c5dab15d0ff5", - "dist/2024-03-19/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "1a93efe919bcb44cae9fea48aa22a1591f041041e7c59e64461ddc3298ec954b", - "dist/2024-03-19/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "0e17193cec07704e02fec9f4393a457f0f57082c86d4833f687a72be0a439008", - "dist/2024-03-19/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "3ccd73bfa0926858f95f1535f1297d6adf8be62afe0a94581d267782b4e8803c", - "dist/2024-03-19/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "e7b4ef2f7a7d9bee1b0dd6a12aec4d52150db2fed29af2668ef5a65b727f6ce8", - "dist/2024-03-19/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "3e755b9a8fc8b66da6795ef57d9d80ed239e10adb17c23a8a64ba96f0d0b6296", - "dist/2024-03-19/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "936807926232e6fdbd2e93a646460ca9d8850367afd82bb56d21245936f73b17", - "dist/2024-03-19/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "168c1fb8b6f633abb699c905eaf4e970ea94c789746d7cc3a7984ffb046df446", - "dist/2024-03-19/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "d64b6a01542d504fe2d4ccdba0e7574e5521841a0a4fffc3d66e78086e0343a3", - "dist/2024-03-19/rust-std-beta-sparcv9-sun-solaris.tar.gz": "34992b0a74cedbaf58057f965858cf26ffdff8bece7b2b0e167c8a1d61b6651d", - "dist/2024-03-19/rust-std-beta-sparcv9-sun-solaris.tar.xz": "957c38d5485d96d62fe46c4dff5726233d7c402708c4dbb0337cd740ad759a10", - "dist/2024-03-19/rust-std-beta-thumbv6m-none-eabi.tar.gz": "7eab40ea23f0758c5ace93224e1268e2929fb7d165b7877ea2540cc2b45664ce", - "dist/2024-03-19/rust-std-beta-thumbv6m-none-eabi.tar.xz": "d0c428c5a1aae6e78842577a5e8f3e4b393d4d3ec9c240ed3c3a0a36d4c0b19a", - "dist/2024-03-19/rust-std-beta-thumbv7em-none-eabi.tar.gz": "450b39802145dc6ebcaad6fdf99b606fda18d3f272f18d0a5e21bffa930ec877", - "dist/2024-03-19/rust-std-beta-thumbv7em-none-eabi.tar.xz": "649532a1c17da2afbcf0fb9395305bb46a76846bbc8c4fd5c153a170b525d35d", - "dist/2024-03-19/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "8068584665ce0468bd420d146cfb4643e745c4ee782b352bfc16c9e7f18ed25d", - "dist/2024-03-19/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "04c1d047e2ec0347cac5ab5591ae0eda6f52c6f9281aaa4d2f4ffcd8c5af11c8", - "dist/2024-03-19/rust-std-beta-thumbv7m-none-eabi.tar.gz": "6e954aeddadbbaf088fc8d671e590eba87d4317f8716a7cca286c764131c0d73", - "dist/2024-03-19/rust-std-beta-thumbv7m-none-eabi.tar.xz": "15f8ea37798f20559f5c6c91c42acd4c883852e14228bbfe5b65865d998beba7", - "dist/2024-03-19/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "1c7b6e92d8727602b8e41d44b66369ddf8e65937fb1a934b2115c18816cd66eb", - "dist/2024-03-19/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "5679ddb9d7404a776861195ca708fc6132ce1e35fc5994946ba7a17ce61afa9c", - "dist/2024-03-19/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "44280bcc42edb6ff3f2d91c8a3e7005703150e7be749480577df96100d516b1c", - "dist/2024-03-19/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "abf86ce8dfd3bd5548cbc8c9c958eb75fbbff77cb7ae8a5e231e5ac9d46d3876", - "dist/2024-03-19/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "ca4fc4970411a503d11a30bbea94487a10dc5925cdf7b1dc3bea095c72e5d381", - "dist/2024-03-19/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "9752a30a7a2dbf64092cfb1901ef4e49e9521b794644710060eaf62c8acd1d5c", - "dist/2024-03-19/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "14d29c09f788bdc63550cb9cc0ecb8040b0e28e6e5a5bc65c06dca6a0fb34821", - "dist/2024-03-19/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "201eff5b741c735547226e9a4d22aed0e09f1c31a48673ce7fc094fb7fc95ba7", - "dist/2024-03-19/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "1a641bcc8c904a0c5b4e7ff0d52d105a1ce45c24d10bb1cdc1dc284222851d6d", - "dist/2024-03-19/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "48f8abb5d1dae87c22e4d24610be6a98d646150d7bddc1ca471a6a27976090e0", - "dist/2024-03-19/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "102f692ecc5233a2e8063c305a0d37ffb9689fc1a4927dcd8f4fa14501a04a0b", - "dist/2024-03-19/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "cd0407c881219b7586500c05b711ed78de9356d7c0db1065baab3833b5d2b738", - "dist/2024-03-19/rust-std-beta-wasm32-unknown-unknown.tar.gz": "3e588580f9298626c4bc3e4b0ad52495d97e4dfc61ca8778e97da3e67c624266", - "dist/2024-03-19/rust-std-beta-wasm32-unknown-unknown.tar.xz": "665dd07fe6ab4d2bcbdc7e88b674e90ff4ea8caff9251d572ff0a7edb32a509d", - "dist/2024-03-19/rust-std-beta-wasm32-wasi.tar.gz": "c0249f7a3e1f8275323adc2a49840cfc677ce8ac3365886753135703a9276572", - "dist/2024-03-19/rust-std-beta-wasm32-wasi.tar.xz": "aad18dde6feaf251af10398b9e7ba2e39828a4640a8f30cc66ee72cd2b1278b3", - "dist/2024-03-19/rust-std-beta-wasm32-wasip1-threads.tar.gz": "95f5700c74feeecea7705d90d3022637e4fa96ee5db165d8fc76d4db05101005", - "dist/2024-03-19/rust-std-beta-wasm32-wasip1-threads.tar.xz": "6787b24af02a7216a524104379517a158938bc2c940b56a60be2ac143d3de7f8", - "dist/2024-03-19/rust-std-beta-wasm32-wasip1.tar.gz": "38d2130daea2bd3c71a456e4dfc44ad900838d15a18af123bfe971f036b43951", - "dist/2024-03-19/rust-std-beta-wasm32-wasip1.tar.xz": "a766d6af0392e913f42930a02fbe5c7b481120ebceadf6b33c7c21ba6067c7f0", - "dist/2024-03-19/rust-std-beta-x86_64-apple-darwin.tar.gz": "3de58d464ee9cfd01d245016b752d1740f9b3feca7c84dddcfeeefd288a4966e", - "dist/2024-03-19/rust-std-beta-x86_64-apple-darwin.tar.xz": "8854dbc047727f11dcdc2f243536a5a6c5e7d8986c4ecea026820630aa2cce59", - "dist/2024-03-19/rust-std-beta-x86_64-apple-ios.tar.gz": "79477ea1afc524ed9d4f3ae57df132affe03a3fa7a14b17214181543918b2391", - "dist/2024-03-19/rust-std-beta-x86_64-apple-ios.tar.xz": "b830688a420e5631406b00d40756739d71a5f8f9789a4b6f4a601db167893814", - "dist/2024-03-19/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "ceb9ac35511e08cbd14dcf6c4faed57107f0facd5ebe1b1634f2ce2b41781c27", - "dist/2024-03-19/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "532b77cbb488b445e0291997a21d0a94c44970c5793ecca07eedca2dc4b02be7", - "dist/2024-03-19/rust-std-beta-x86_64-linux-android.tar.gz": "5333bf0c8ea592ed316e21bb2938ed07d247f0f873b45f34abcaa62f2e33f741", - "dist/2024-03-19/rust-std-beta-x86_64-linux-android.tar.xz": "ab18128d48a1eac2e8577e4268d95efe9619a4789cf4ee322d5bd651f33c24c1", - "dist/2024-03-19/rust-std-beta-x86_64-pc-solaris.tar.gz": "6976af5df3468680d83f54e87f57b94ac121ee82d7887e3e21200434b993a219", - "dist/2024-03-19/rust-std-beta-x86_64-pc-solaris.tar.xz": "932ffbff886919acb32f77ab70560a0262bbf5ee83a78679598ec13fcad39e3b", - "dist/2024-03-19/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "0429be318b55a9c36bc2fdb0b9654a3cf39527cb05d75f46890f6fcc2ed003a3", - "dist/2024-03-19/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "7e3f64dc9b5b6653e6adbc58499857c0df8f1765d8fb777f6cb2ada3f40543d4", - "dist/2024-03-19/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "07a7bb2d07bb72693e0bf0ddc365394dde55063ad572259a5d171e08cda592f2", - "dist/2024-03-19/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "efc20d952b248815bda4ab3950b2998b5326e2c5008e72ede921eacb79b3b504", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "04a46c5cbfe620dc5d3d05134e0501aa466c081f848df679c554d51ecc6e8bb6", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "9ed41c7d0c09409fbecf33eab630ec847a4af7ea5bcaf42d8e14e1074ed30bf4", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-fuchsia.tar.gz": "de0c88a91d325087e5c28e9ca5d3092443c875b55ed08b8486e8fd1c01c7b7e8", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-fuchsia.tar.xz": "e403921f889381097628bcb2c431e3b8a8c0773c0d5062d4d1a9ec8e7f88fa45", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-illumos.tar.gz": "ee045b5102673d085fbeead4d5b9daeb9497f90d341bd51c8ac85b666e9c9821", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-illumos.tar.xz": "bd24fda28c9b69cc68c90b910a75cd652ad3b4d4430f802d8a2354c2cd5d19e7", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "8c70c2d12202054329cf6fca88adf20d9d9f493cb057c30211454a49f96ad4e5", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "ea6673ea519a6eba60836b810c0531cac858ca74d0d756538a45a375ffb7db9f", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "52e104ce39ac5e8e44fbb332bc08f7ac3d564408f48a459f79ba2149caf47b32", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "fa098772e186acba6e85ea2f4d0270f01e00cbdd27eec1e92cbda808b7807284", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "d6785e6574b4a7ba61f66c1e7938a46a02f9430983a7aee1c3400eb5f8b57f0f", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "17c3e8254fbfed0f0a9b3209976e44a136d0f581d0713ddf7114753cfd0b983d", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz": "407f9c2d5d3bd76698af04711d9a06b7aa86d4c55cee9d8ed1ce3aa37055068e", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz": "5e0869bf268c9824c284e841b2bf5a13a6dc1bd2e55ce3b7b09788ba5608c9dc", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "9b5aa240c2a696af0d342ec26a6b6ea4f5888070e8b590122379302910a978f8", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "064c1925a8ac82d1474c240c6c9414b422a7b04211a49a7660625193a0c21c64", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-none.tar.gz": "8e48a645b2b8dda6deb5b706e415697d303830775032b69521265acfc9f8608e", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-none.tar.xz": "a3d28304c75a71680d7d40aca43bf638bb4def5ec10f873aca5261692b114743", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-redox.tar.gz": "e645a81d4884f09c9d7da242ae448cadaf7a9232475707ece014a57d02a23527", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-redox.tar.xz": "0cf089464b1949a4f24092e2782b306e9530489cc415df69ae433c23a438518e", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-uefi.tar.gz": "ba7eec56d4e8a5f8a6c206b6a12fcae77da9a24ffea824c1db128dcd4a7d9fbe", - "dist/2024-03-19/rust-std-beta-x86_64-unknown-uefi.tar.xz": "76aa9bf6ed668667d1d47feb2fb8e941f5446f2ce5b4e94aacf34f964ebb3171", - "dist/2024-03-19/rustc-beta-aarch64-apple-darwin.tar.gz": "e40614daaa2b0270d5f3153c8216f68419b96dd167632dc67c1fd641ac0a21ff", - "dist/2024-03-19/rustc-beta-aarch64-apple-darwin.tar.xz": "7c2106ea1a3d358e2893a62fcc2162e041ecbdd9143f2dabbe0fa7a6b5827aaa", - "dist/2024-03-19/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "7eb0678bc1b4dfcf366641dbb02390262e47ecade1db9007ae1d5bbc39b6c7c6", - "dist/2024-03-19/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "0caef4825f0a6e51fd05c5c32365fb3a80a2b7692de71ff0af10ce9aea1ecafe", - "dist/2024-03-19/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "bbf59310c1e60725aebed09a09f0df4b1c21c2d0744f34734472e46cd7248fee", - "dist/2024-03-19/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "a7687c89bf94d64119ee76029ed12d27d594d7716fbf542852333185385a5b44", - "dist/2024-03-19/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "d2bda016eaf8b988e3b5899ab1239c582ef9119c40267b79be2efa453ceb9ee1", - "dist/2024-03-19/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "940f0611384175521401f352f4fc18a587b3816f99c88a0e130b895918c340a9", - "dist/2024-03-19/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "3ef861f5980f899b6575e50844c14ad30fe739f80538118acc8e29fd8b00cbed", - "dist/2024-03-19/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "191a2bb6966e05d1db83acafeb3caf0e0421eec539e221837e3dcff5e9db4152", - "dist/2024-03-19/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "9999f60a513864257a14ee58ac3b87d9e557e0c2fe720a5d4ba31d250debc378", - "dist/2024-03-19/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "7c824f67a45aaeb7cf4c7519aa72ce8a81013cf2edec2fb5600f68aaf6eaf84e", - "dist/2024-03-19/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "83fa3927f92945845c6cc5a6f123ce5301a24af81c9371e5c6bcc8964a182688", - "dist/2024-03-19/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "3469f087248e671351dc0bdda06c1a9b8d12fc64854148cc9404d419db8fdb02", - "dist/2024-03-19/rustc-beta-i686-pc-windows-gnu.tar.gz": "a219c9829d7e33a822947faeb3f8826d7f2f5c46aeaa9c338bc27bf7b1561395", - "dist/2024-03-19/rustc-beta-i686-pc-windows-gnu.tar.xz": "ee5f30b90bc43738eb9c9a3678a09768bcffd3bed413c50ec23fa14fea1157ac", - "dist/2024-03-19/rustc-beta-i686-pc-windows-msvc.tar.gz": "acdc6345b76ed52b5b58d2832ae61c904aa6d74955f2e31432ab363f217397ec", - "dist/2024-03-19/rustc-beta-i686-pc-windows-msvc.tar.xz": "13161baa6a6e0771fcfb65b0e26f77a1ce07c5dcdb029a624723231d5d3c1012", - "dist/2024-03-19/rustc-beta-i686-unknown-linux-gnu.tar.gz": "7188f7c598cd4f1579ca06819cac5461679513ff648f03b7f28e15fd5636467e", - "dist/2024-03-19/rustc-beta-i686-unknown-linux-gnu.tar.xz": "42e03380ac0070f1cbf47c674c1d529cb065960f5e8c0f92e24a5f994dfeca83", - "dist/2024-03-19/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz": "67a57b0a8a057a1d39b99e5232145d7c5a48b9e3ff0e97b9ad1f4cbda004587b", - "dist/2024-03-19/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz": "1c85e17bd524294ac64c2defce82eae336cc3c5d9795dab68e0d7419ede35a6a", - "dist/2024-03-19/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "1c243f95e823164a4b112fef4a70bd3cb0f368dfbff7efd106b7ec3a718f49dc", - "dist/2024-03-19/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "318d69391381a142b72a27c6e53be624691e465ffec2497676c2454bdc06f856", - "dist/2024-03-19/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "f8423ac9a207c9a43746b9299dab7ff55a747aba1980313f98b5aef67e489d66", - "dist/2024-03-19/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "f6e3552a9ad8a90dc0830f7c8beaaf10c90e4760bcb48904d4197c53a54a8b1e", - "dist/2024-03-19/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "3ab2d798cf0812b874198691993686e9c884d24806628242110dacfa5bc3446a", - "dist/2024-03-19/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "6cae9a4e5e88054800f11f028b92211173de4038ad1bb0a871cdd05bc6a0b8c1", - "dist/2024-03-19/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "368351e98c1e71b3fe40c687f478d52a43ba388811521e7807b314d750cb4f65", - "dist/2024-03-19/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "116171252c2f153066e9f8fa6eb1e63962aebdd67d14368560200c984ae38ccf", - "dist/2024-03-19/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "0445ba1954a7e6bbaf64561a33c01988a4f48aa8401669acd7c5e8ac11d27696", - "dist/2024-03-19/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "23aeed13a2c0143d14ab9fb26be47314318ee3014190ba08f5889bed14205799", - "dist/2024-03-19/rustc-beta-x86_64-apple-darwin.tar.gz": "91a1040d4b0d309fadae1b180c5cdf30c9c073245599064a075849795a8c84d6", - "dist/2024-03-19/rustc-beta-x86_64-apple-darwin.tar.xz": "996bb8bf522509e5ddf5e2d4fdfe0c19d4198605107575faba4a80e1f4de616c", - "dist/2024-03-19/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "82024a5d02148c7a0a0309105114f54dcdc6b9bb763d1e0456f0c18f96b16f57", - "dist/2024-03-19/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "b6c00535af0ef5815cfaf88bcf21b83935539785345b22abeb9d4fa97e2cc445", - "dist/2024-03-19/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "409a22e9a1ae89640059cb33d614abe84eef4096817b0fa750b3a38e0a153061", - "dist/2024-03-19/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "8fcc030bcbafdcfbd894653ce935ecb82fc04b3717718d34dd6b2a4e8d553889", - "dist/2024-03-19/rustc-beta-x86_64-unknown-freebsd.tar.gz": "79d39890188af98e9eaa1b5a15606517ad7e0b3c493bad09a59c5400bfff3d9d", - "dist/2024-03-19/rustc-beta-x86_64-unknown-freebsd.tar.xz": "b69b370559cdf73f26b83a4b5276d10988f44d39d57608c44defa6b79f92121d", - "dist/2024-03-19/rustc-beta-x86_64-unknown-illumos.tar.gz": "f4bc2b510a230a09bae4b243f1297863907c9239a94bdf739f43c31a76238a04", - "dist/2024-03-19/rustc-beta-x86_64-unknown-illumos.tar.xz": "131b02eab07b50d8a99e0185090afd6c3fd1bd20b98fc0a4830910fea5b12ec5", - "dist/2024-03-19/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "ed9d98b20a4868330c88563ec367078a4c5ed7bca497680ea690cb9da2d6ddbc", - "dist/2024-03-19/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "b6c0fec4e295b8eec2b7c8bbddec48aaba1d3c4d73803eaf887554d368b4efa5", - "dist/2024-03-19/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "e972c5ec3f9cc2661845bbb2e7153b9e90e59af2d4fcd74c588e3f326bbe9e6c", - "dist/2024-03-19/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "d576799dcd59b48ddb6d96545ec48ef517b5a7d9875033de6583387fc1d4b79a", - "dist/2024-03-19/rustc-beta-x86_64-unknown-netbsd.tar.gz": "39f5a43f70692f1bcfc6b82ef901fa86be82aa7db0f6161ea5025577976a0780", - "dist/2024-03-19/rustc-beta-x86_64-unknown-netbsd.tar.xz": "596e6681bb15420754ab1a7210157884f5e31b34a885b1d1cfcb8838ba5c28b3", - "dist/2024-03-19/rustc-nightly-aarch64-apple-darwin.tar.gz": "f91204bc62d9236adc75e2a7ba4ae41e0d9ea9c6b6bcaf0d211459cfc7d17d21", - "dist/2024-03-19/rustc-nightly-aarch64-apple-darwin.tar.xz": "7562f89f9bc9f2968ddcef0258cd5a1435855d87a1c40b9ead6b82c1cb5c58c3", - "dist/2024-03-19/rustc-nightly-aarch64-pc-windows-msvc.tar.gz": "2f1ab532837469eba7dca3cb4b45ce983384e30917b0af3108d2a8c7c88f38c5", - "dist/2024-03-19/rustc-nightly-aarch64-pc-windows-msvc.tar.xz": "fa69006e8189b1e624e0d9a9a212c15423fc1b428785f651a309eae045199f11", - "dist/2024-03-19/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz": "21905a47c616e3e43b05135621c17db635dfa897e2e64b124c03b042f74dff00", - "dist/2024-03-19/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "1efea63747a88b3baefe6602e047e84323867a3eeb77093b9e662ff254a85f28", - "dist/2024-03-19/rustc-nightly-aarch64-unknown-linux-musl.tar.gz": "1b693de287b60428bc1a0a23088c08680db2d0fbf4f7cf0d6e3f413cd9cfb150", - "dist/2024-03-19/rustc-nightly-aarch64-unknown-linux-musl.tar.xz": "7803e124610ad092f88b7cf4b65cd3fa1a80cb2cf5a36fe4391535ca4f3d9369", - "dist/2024-03-19/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz": "744bef406b6df5c610b605234375d8520abe24d8407b8bd22a0fe15de41d62b6", - "dist/2024-03-19/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz": "b90dc87a68c134e6fcdaa3ea20e9d0fc33b0422e4dc989c1cf0c85c8140fdfce", - "dist/2024-03-19/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz": "e235fd3258b7d1e42ff6609f1660a94aaafc00875c371543ad2b12ae226dd8c7", - "dist/2024-03-19/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz": "b37ea15820c88ae1ab534277f8f7a7ad18b3d365f1d2d499a887665b715c6c21", - "dist/2024-03-19/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "bf7cb8f0b21f2b0b8b067f88e31a2ce9e5754044b68437d4d52324fd95010161", - "dist/2024-03-19/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "3595940730b4cbcb00e0441458b07253677d148f4850b464d6df7706c203d1aa", - "dist/2024-03-19/rustc-nightly-i686-pc-windows-gnu.tar.gz": "3135f03a8388c13c6439ef0464e2086949a528cee7bebdfb955defd59e55952d", - "dist/2024-03-19/rustc-nightly-i686-pc-windows-gnu.tar.xz": "54b6ca29f64e454189f27135f9a40f0bc0d0b5abf4d2912aeb857f733721005e", - "dist/2024-03-19/rustc-nightly-i686-pc-windows-msvc.tar.gz": "d3b70b07c8c9cedd30dbebfff2bfe45316752a13d49c9feedfdae4f71bb74865", - "dist/2024-03-19/rustc-nightly-i686-pc-windows-msvc.tar.xz": "653a821d9a7789e19fdd32f82466e906c23e03e42752f7277c05b692c1459e20", - "dist/2024-03-19/rustc-nightly-i686-unknown-linux-gnu.tar.gz": "4a37e87a3280997bb09deb6a3617395b1e898ecd07f0bd5469cb21e55c3c5f81", - "dist/2024-03-19/rustc-nightly-i686-unknown-linux-gnu.tar.xz": "a66bd9287cc958a61f9989d5efb6162255f7eb9211af9a4ea98769971350384b", - "dist/2024-03-19/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz": "3ce931c54c96c72034392efcbcd73061d6f8a7c7f40f1e86c14ae6fd5248d2a6", - "dist/2024-03-19/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz": "cab19b60b91cd6549f89398f46b31fe440323c9669606f48a4029e8d3cdc1ee5", - "dist/2024-03-19/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz": "3d50b95e8f9ce5a2721e1ba0649378e8426fc4ba531bfa13bd9b96ef627aa46d", - "dist/2024-03-19/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz": "9286d55547a438008574267cc3a067ca50005a9397bf8aeccd76ea27233de2fe", - "dist/2024-03-19/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz": "61843b55a45909408b3005cee338de42d31aef852155c8bcd8f6cf9aa3077dfa", - "dist/2024-03-19/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz": "2de14af7b540c3302e6b1a0f77472362429c0a1a0026c2fc799b263817e3c942", - "dist/2024-03-19/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "816575061e2879d6855fa497b3bbced57f3201d64c6649c89ba9020c69889fd6", - "dist/2024-03-19/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "58962496e51cdc60f9a98fb2fdbbb2f4124beb3fdbb065cc6b52871eb4bdc2f9", - "dist/2024-03-19/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "cd649970e9b8a98e9dd0c1f506624832cb08516aa9cfd001381ad265cc42ee66", - "dist/2024-03-19/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "1a9a2bcdd263a205bd85c8fbb9733711ceeee372953a7573420fcb55d59d59b0", - "dist/2024-03-19/rustc-nightly-s390x-unknown-linux-gnu.tar.gz": "98d6631c6dbca97491d5f518dceddc07c53aa309c7db8da0a919eed96f9e45bd", - "dist/2024-03-19/rustc-nightly-s390x-unknown-linux-gnu.tar.xz": "ee1fcc2a1d3181c2a7b97df8525363159c47b1348c0db78f74c7181ad6c44166", - "dist/2024-03-19/rustc-nightly-x86_64-apple-darwin.tar.gz": "c2768511ca6e9c228e13815040eb56f43ba1ec223c7753ea0e613400989a20d9", - "dist/2024-03-19/rustc-nightly-x86_64-apple-darwin.tar.xz": "6c10e9e824d1bc7a3c75172375e3490e33627bcaef6315552147b89b81ecf328", - "dist/2024-03-19/rustc-nightly-x86_64-pc-windows-gnu.tar.gz": "6d3a1f7c97fd4115b524f990426b795be1b9ca9a10fc6fd68db1cf4355d3953b", - "dist/2024-03-19/rustc-nightly-x86_64-pc-windows-gnu.tar.xz": "86fbb08c51664be63b234b82894b1b8012d8f6bbbbd96b6fc7188c22b887049e", - "dist/2024-03-19/rustc-nightly-x86_64-pc-windows-msvc.tar.gz": "39b673d694aee6c5d25ba88ba7e9f38b6264f01ed6a5785ea44e07594b9a7d1a", - "dist/2024-03-19/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "43ebc08539300d736d1d41af2306b1bbcb0d9e04795033725807d4c9c06d590a", - "dist/2024-03-19/rustc-nightly-x86_64-unknown-freebsd.tar.gz": "cd263eb4b6e027b834723f3748139db6f1742f885c2cfa2a4842c23c806b48fc", - "dist/2024-03-19/rustc-nightly-x86_64-unknown-freebsd.tar.xz": "22fc109ec6293b799fd52398b72f90966b9efb95c433f826e31f54fe643132cb", - "dist/2024-03-19/rustc-nightly-x86_64-unknown-illumos.tar.gz": "20b01c262d54731c471d6dd856fbe8c9a58674f88d0dea19c7e9b7adff6b5474", - "dist/2024-03-19/rustc-nightly-x86_64-unknown-illumos.tar.xz": "584d1e3b9e6e2006767a6a1a46aacff34a2042b4094e51be0a1a82a50a4ab27e", - "dist/2024-03-19/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz": "71b98f184c4b3f3a40c5ab7cf6bdae6947a39c2a7e36e590750a37806cd98a2f", - "dist/2024-03-19/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "44510c19128801a465c70fbb4d1fa0250edd7c1ff0a67f1c374f1d921e1a4bb8", - "dist/2024-03-19/rustc-nightly-x86_64-unknown-linux-musl.tar.gz": "897728aae12523d33bad792c4275512383ae5cff008860406882ebeb273cca5a", - "dist/2024-03-19/rustc-nightly-x86_64-unknown-linux-musl.tar.xz": "b027abf370ef289d6b2e615dcafac3eda20c147dd2ac4a3c113e8689f6936655", - "dist/2024-03-19/rustc-nightly-x86_64-unknown-netbsd.tar.gz": "97360bb700ee986b0a36ac4ed4f0fbcf3c875907bb6cfdbe4bfa0274893109f5", - "dist/2024-03-19/rustc-nightly-x86_64-unknown-netbsd.tar.xz": "e8414dc178f2d1939b2d6411beda7bc6f8e9b7f500ccb30fc8a8659ddc0f945f", - "dist/2024-03-19/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "8515050a52addca9d5c0ea8b9f4e5c536d32ed275fd0922cbe567fbf7d5adcb6", - "dist/2024-03-19/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "97c68112bd8f4cd67eef50c994dd13967482ac1e55170dfd11d8505c582c689d", - "dist/2024-03-19/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "b3ff60427dfa13e3c9d4965e0f197ac2a0625fe64cb1e23ec46604adbafdc847", - "dist/2024-03-19/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "848938bd1436276ba813104cde9d969cbcd79d295eb045ced1d82080cdbae29f", - "dist/2024-03-19/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "063f25121c6a8055228763240f178b7f1e9b55f20b305b8e2ebc1b0a080e432d", - "dist/2024-03-19/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "89ab3a28357f3926fa4880010d0ec6b6fce06476050f42c71416c60528490f7b", - "dist/2024-03-19/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "6ece90be16f59b3a5871d8cee8638e18c233eb0e59253875e71bd16ee4c7eb76", - "dist/2024-03-19/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "7272af79200e1da8ab80b2e4408501ef8a54c24ba44420aaab0fb03653933ad6", - "dist/2024-03-19/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "7ba3404ab333e43dbacfda6d8860d800721a7f894c672d3ea88cb88127128c90", - "dist/2024-03-19/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "bd4087d9e70c0246c0606015c1e6d6b974c068118e50e2720c7ac75a6d338709", - "dist/2024-03-19/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "f87c7036539d18881cc0ad5647b523dd07cd29cd38c36665aacbdb37de316231", - "dist/2024-03-19/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "cd1b05cde5ccfc389df6d146f467a18455f22c7f23e508537c8de11b8d7aea4f", - "dist/2024-03-19/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "66b0bdfb271448861ccc403d7549b49316c5cda81bbdaa396ff66c01dfb052df", - "dist/2024-03-19/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "40e3df123160c8948ed06c8228df90de1368d286f9849a0a14de0725167dc8dc", - "dist/2024-03-19/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "da09c72f472b6bdbf7e794d84990153936ad1c7d275daa75b506ab72444b51a0", - "dist/2024-03-19/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "c9e2ea2216c4f7737919c63ed0e5ca362f6c3c9f227f1b3e6a243a870f229a52", - "dist/2024-03-19/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "ba468a1251b4bdb685cf5437222ccea45ba1f4d1b25ca65b82a9fae4ba93d6d9", - "dist/2024-03-19/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "64781d2017662c9973a22d322c92b242703a90895cefa584035b0d80ac966541", - "dist/2024-03-19/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "595fcdf3cf5b2511ec828936119334516d535c4dea95f60a04eaf1724a90a276", - "dist/2024-03-19/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "42f2537e87adc2cadee67e5dc1fd7fee4c7bf4347f88501752080a65b9e7fd89", - "dist/2024-03-19/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz": "3ecbee26e0b0cc43189dbd8d69a563bf71292974d0c5d313528a32012f38fb56", - "dist/2024-03-19/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz": "7a0918c6ad0dcdddac757c7f4580fa57ca188ff2edbf7eac07ce01626666bc95", - "dist/2024-03-19/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "08197220ca270180ff4d7f484000f6b7a52800e932937238cbf1f47ce3f1080f", - "dist/2024-03-19/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "dc7f03fa39872e59fab5f4d663ed092409849c62c8e4c958c6cd4ed59bc05902", - "dist/2024-03-19/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "c7744b4c88a5ac7ddbaa1b61b66b39f2799863c50b6e18c18874d5774d11fe53", - "dist/2024-03-19/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "0ed8aa4704e7d665843ea1ac532b1631cbf449180331d880466fc69483d4cd23", - "dist/2024-03-19/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "e67d83663cb54168fded400385a5cdf8b74c6483d91fd16d03846a6411ab1afb", - "dist/2024-03-19/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "fe4c2401281c07d1c3ed335575bd192ac57396973a3676226d57e5de32a63e3d", - "dist/2024-03-19/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "39c4739ef0281bb1eeade5c8f7360ee8dde5a8a7ae148b0f263ba650d092cced", - "dist/2024-03-19/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "ea26063a71a4403a4aa49098a96a29b48aab5f9b9177e57b1790b92ed749ae1b", - "dist/2024-03-19/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "49591c34bcb82d6cc5c08c662c4c89aca07b406fa1b48b78c7dbcb63cbe6fb5c", - "dist/2024-03-19/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "df664d781e8104015c506178df751ba7130c677f050cae695428fbb6180b1af8", - "dist/2024-03-19/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "ff20c34ab85505c1957a677eb8123622c98f5e19e87cfa38eae76232e200242b", - "dist/2024-03-19/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "c4e8b76738bbfddf94defb88e9b0c0d0c488d9a5868f2be629322c041391b43c", - "dist/2024-03-19/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "8e0367ab0700e916956db6041e1c6a35b0c6fbd1127a17f9482691a103dc8d70", - "dist/2024-03-19/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "1aad45bb09a907effb39378acf5c57c741d7b0e29eec957d8be31eb1bf47ab23", - "dist/2024-03-19/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "f5fa93652040ba991c429d11c5e9ae2e76aa6f21f6850a777f2ba1b065e943fe", - "dist/2024-03-19/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "7d448e8ae9090467197d9bfc7ac3d8f7ab81cfdfd0be140afdbbbc6c3cf65295", - "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "8ea5bc3f374b5b63432151541715ab41d00f265e6cc8e57c61e175304363ca5e", - "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "666deba3f55f30e302642b3e2d3c86bdce12626ae78bb7134c7d90b1c7179592", - "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "edf75305baace32ab2955131357e30c73c736d823d6426125e5fde213c8f4c61", - "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "5b3ebd05d571474002c032aa2fedc788650d374b388eff9f6c00cf5bcdd10c08", - "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "e795bb7cfde3d71f9e964dbc9efd930251eb3209686d5c9348f24deecb01fcde", - "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "8e1c06e91fe7cd1ffa80f043b8342c611d8f923cc9b563fda0155855d8799660", - "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "a8a51ce3eceed87d192701abb699dc60dd3c28c86622b9aa3dae833feb8207ef", - "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "389cd5d4c0decb87eb24b9ce88d5e5f33a7292153e2eb37ca2a106e4f8a4e256", - "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "cbbdca68aa3ff10fb28d431ddd08b56bb4f0a0f85ebaf7c094b9740c8e2d1aa2", - "dist/2024-03-19/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "e1c1793bfd102241338f801ba8c28f83d15fafef09046b231e30d1ac42b5e372" + "dist/2024-04-29/cargo-beta-aarch64-apple-darwin.tar.gz": "5a8c5e48a88e7c7b41eb720d60fbd2e879b97639c7ff83710526e8e6caaf8afb", + "dist/2024-04-29/cargo-beta-aarch64-apple-darwin.tar.xz": "0d237535ae8d435d99104fa5b9dbf41878e2304bb0f2eb574bf17dd685caadc2", + "dist/2024-04-29/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "c56733bb6198af0a9b0df9a44ef979150e00de33b70853c239cccfcce23c328f", + "dist/2024-04-29/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "7da5f887151215ddec640684077d98551fe2aed75a3ece2c73b20698754a70bb", + "dist/2024-04-29/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "73851e304a539d41bedc0d8a5d98800c8279ae623d3e58e863f8c1f8b458b01c", + "dist/2024-04-29/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "db9c28841344b0154756e19a21795ef6e0c4e27c7844be9996824f1039edaa81", + "dist/2024-04-29/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "a706c8c7e37b9e80d7faa000c5d179a772746eef071387fb2879fdeab1f1f891", + "dist/2024-04-29/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "2060634afe1b4a19bae874c6ce3cf4256e613af26e06104b45da5bd71cfb133c", + "dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "7af61e74faea669fdd41793e4b88eb6a37bfacf845af364ee02bb7cf08c612c7", + "dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "4759fb3e3d89ead605c4eeba23be5cb9b3ac98086a9de20f8dbfdfa9282ee486", + "dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "4cab18df2d94702e8b551357373bcae60d1023e644148f0f82e8971023362121", + "dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "7de4f0d72b4e5770376ede82b02d6bcfd450788a40375fad34d75524c941d72c", + "dist/2024-04-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "6401391a426cf33d6c58f07e7b2828b178720cb4f2b8577ae932b5f5b7d6744e", + "dist/2024-04-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "c3f6729bc769325046f0f62c51b5bed30068c37dc2a36a6283e50565d8cb7d5c", + "dist/2024-04-29/cargo-beta-i686-pc-windows-gnu.tar.gz": "d116c97c1242220c7972b63010aee1ed36bf5353e84a06d3561cd5fe9d7dae84", + "dist/2024-04-29/cargo-beta-i686-pc-windows-gnu.tar.xz": "65eba577f7775b3eef36e7f000b5007264392b20a7759f8ed567f3a45b2877db", + "dist/2024-04-29/cargo-beta-i686-pc-windows-msvc.tar.gz": "d418a3371b3631328bde2b1e0c3159700f12424e83b1d8ece1349fea90f9e403", + "dist/2024-04-29/cargo-beta-i686-pc-windows-msvc.tar.xz": "23ae73c776fdb0795944656d743444e3b4c440f45084028206c1aec52333b1ba", + "dist/2024-04-29/cargo-beta-i686-unknown-linux-gnu.tar.gz": "b6bbdeb7c8bfac2e8a083adb4782caf5321799f47acb4eaf81da32bd11730e9c", + "dist/2024-04-29/cargo-beta-i686-unknown-linux-gnu.tar.xz": "6b409691da6ddb8c04409667b2c3d9d6429c6b5bf53ad18177248406a5f06cb9", + "dist/2024-04-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz": "24cd888d14a788e8fb5b886735f3c07a028a8681df48a777b2bb971c62a175ae", + "dist/2024-04-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz": "e8eece6412936fe4dc863a5e19e6766fbb20e81da0069ad7831465e638db23da", + "dist/2024-04-29/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "8f007a2aa02e35c5ddb2152cc7589092a0e3083211c6aa23e676e3a3ad5a4b8d", + "dist/2024-04-29/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "3e423e693dd0813f5d87d9eded94894076258ece56684f3598321cd013aeef3c", + "dist/2024-04-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "2eec5e45e389a52b526a5cf683d56a9df92004f6095936b16cd8d7d63722cc6c", + "dist/2024-04-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "64c5135cbff9d4fa9575074c55e79d85f72cb1783498a72e1f77865b9b2d1ba3", + "dist/2024-04-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "d64552a80ca386728e42f00d7f1c700b5e30e5a6939f32ffa15a7ce715d4c8e9", + "dist/2024-04-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "fe91adce8ba35bf06251448b5214ed112556dc8814de92e66bc5dc51193c442f", + "dist/2024-04-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "77aafa8b63a4bf4475e82cd777646be5254e1f62d44b2a8fbd40066fdd7020d3", + "dist/2024-04-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "c38f0b4adcc8e48f70b475636bbd5851406bba296d66df12e1ba54888a4bf21a", + "dist/2024-04-29/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "c05df24d7e8dff26c01055ad40f9e81e6fcb3ae634ecc1f7cc43c3108677fa0e", + "dist/2024-04-29/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "47e8f4ec4d996600e60ddc49daeeb43d4c21e0583a86c12395c16eddc7db76ee", + "dist/2024-04-29/cargo-beta-x86_64-apple-darwin.tar.gz": "f024bd225b77160dc2fabde78002c8deac5cbb9a35345340964c3b988b0d1791", + "dist/2024-04-29/cargo-beta-x86_64-apple-darwin.tar.xz": "96c9e44bd9f0c85c793e3dd6043cc4f89fbeeab5ddf0fdb5daefca8f690bce05", + "dist/2024-04-29/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "517889f222b62150fe16bcfd3a0eb5f353956b0084d85713480197bff4558145", + "dist/2024-04-29/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "a6653ea4aec51569c1300c044d8bf2517a1f5111f710d12cd352190425b8f317", + "dist/2024-04-29/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "4cb5b5054dffe6721efbbf29192a67e59cda69ea4ab4791aaec6f314eefa5a5e", + "dist/2024-04-29/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "08bc45be22e9e4f615d1c9e70500046c8db89045f5d40dcde853c610591712a7", + "dist/2024-04-29/cargo-beta-x86_64-unknown-freebsd.tar.gz": "9661357ee8ea8973016fdbaa2de3cb98713136dcd25f07aa9f9d101180276815", + "dist/2024-04-29/cargo-beta-x86_64-unknown-freebsd.tar.xz": "7fab806227d1a3be817602abb121ac7e039ba0bbf81e0a1d47bdcccca74203c6", + "dist/2024-04-29/cargo-beta-x86_64-unknown-illumos.tar.gz": "4c79bb48cfe64bd38af7fe3660cd8bdc99ec90738a0d8fdf80843ecda910dab0", + "dist/2024-04-29/cargo-beta-x86_64-unknown-illumos.tar.xz": "0fb9edfdafde1820ccb25c22369cafb0e75e68795effeb615cb284a5837c75ba", + "dist/2024-04-29/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "c1902a072e61ab5ae9737a1092732e3972deee426424bc85fcf8702adffdd41d", + "dist/2024-04-29/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "d39ea1195dcc95e428bd540abd2db5b5d4c997a7661a41a4c0ca41cbdd18d27e", + "dist/2024-04-29/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "0edfdb6f6bb2a4a1a96a5e95cec897c444c936e6624bb4a530ffed4847b97445", + "dist/2024-04-29/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "70c264b7845febdee45d0c6e44b65d47ba7f367ef33ec906a9fd7f992ba7cc13", + "dist/2024-04-29/cargo-beta-x86_64-unknown-netbsd.tar.gz": "f1bd6417a54f3b53d572ce4af799242db7c11265c71201cc09c78d71be38c13a", + "dist/2024-04-29/cargo-beta-x86_64-unknown-netbsd.tar.xz": "53569810469c483785333759f86434706ee5368d5e18270ee13a17817ad57d40", + "dist/2024-04-29/clippy-beta-aarch64-apple-darwin.tar.gz": "7b693bde61a090854527a145455ff774314c65ec0cd47d25a19c76c6a166d96c", + "dist/2024-04-29/clippy-beta-aarch64-apple-darwin.tar.xz": "2494e9fdd8d342b6bc3e55eecfd555c43e3cca8421f3236df2d5a366288fec62", + "dist/2024-04-29/clippy-beta-aarch64-pc-windows-msvc.tar.gz": "90307f09c6fcb0c1fbe3ad1522a5381a17e2f69637c6d00f4a2cb5f3149bf736", + "dist/2024-04-29/clippy-beta-aarch64-pc-windows-msvc.tar.xz": "f7e0dec4a4862bd85d894252366152b3b6a7627e7e5a25ce323fa2db3bd87c2b", + "dist/2024-04-29/clippy-beta-aarch64-unknown-linux-gnu.tar.gz": "7c719e38f2a1030ae61985205df52f9a0c37b659463a5e2dea8e60e632de2d73", + "dist/2024-04-29/clippy-beta-aarch64-unknown-linux-gnu.tar.xz": "181ff4ae6adced6522a4c29869be3cc5dac8b961c7c88f2957cd31f831490807", + "dist/2024-04-29/clippy-beta-aarch64-unknown-linux-musl.tar.gz": "4e0e63e6f200386995e369a2673867d1bc3005d51d6a57c00ca80056dd85316b", + "dist/2024-04-29/clippy-beta-aarch64-unknown-linux-musl.tar.xz": "3d5b22a13aed6821482e60d9cc8571e2da9d95d82104284b77c56985a35a9c4e", + "dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabi.tar.gz": "9f788db76a5d55b3ecdd04a70b0e2be466959f76ae9fd3497ca2c503504e0c03", + "dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabi.tar.xz": "f4d8fc103807fba61d71d88b8e25a7016bfbd1a2905330f9a9fb3d7ba082713a", + "dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz": "d61bec3d017dd0be43e48350190ad18c0a0269e43d964600b62e1f7fd4f84399", + "dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz": "c00cbdc41a4da0c313a1a282b0158b059dd34f640b582cb7ca18e3d290ca8fa5", + "dist/2024-04-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz": "52143a530ca5274fbb760beecddff16f860ea787443d3dc708dda7c8f32ca9bd", + "dist/2024-04-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz": "c6d2dfeac6f40811bc9b4cec3c23f9c3bb46f761e006257b9313aa7c1a647b5a", + "dist/2024-04-29/clippy-beta-i686-pc-windows-gnu.tar.gz": "325d39e426b1907fa17d93c0752d3d73bd95750f4f967c2a84aab2c5dac8a588", + "dist/2024-04-29/clippy-beta-i686-pc-windows-gnu.tar.xz": "536f591d4da455302029384ed196932d71119ef0160ac5415617d6b777c51123", + "dist/2024-04-29/clippy-beta-i686-pc-windows-msvc.tar.gz": "c3684c9bf471669d444853bf484880d17e150ecb0e7505de90883382023e343b", + "dist/2024-04-29/clippy-beta-i686-pc-windows-msvc.tar.xz": "0b00e6132f73d5dc762e359b0005fceab0cf7b01337d8f4aa9eacfb4552f9245", + "dist/2024-04-29/clippy-beta-i686-unknown-linux-gnu.tar.gz": "c91c1eadfc4cbae360a0eecf11c32d2509b68aca86c7b1de3b102944f43e1511", + "dist/2024-04-29/clippy-beta-i686-unknown-linux-gnu.tar.xz": "6f7a5a287dd6226c203bb674ff02ec773e5d0813091b2af744b88ecd6997a304", + "dist/2024-04-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz": "58383f094995823ea6db6a87b9ad4b33bdae2264d29bab88ab71ec60ccab3b93", + "dist/2024-04-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz": "dbf4680a6fd4dca54acca5503a7fd94502b8e85819bc02346ae9cecd275e4514", + "dist/2024-04-29/clippy-beta-powerpc-unknown-linux-gnu.tar.gz": "e28eb32cda42654c0f0247aa8e15f01f73770b36f7626c8d6f1b7659accc56e6", + "dist/2024-04-29/clippy-beta-powerpc-unknown-linux-gnu.tar.xz": "fcc48a83b748e1e46f9daef40563f8e5abbb0e3f014a168b04f3c700c2ace2b8", + "dist/2024-04-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz": "b626faf3275fcd196cd627e8a36c67721bae16a56f61cd080c79d137b3ec7737", + "dist/2024-04-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz": "2c599d2dc719d69f67625f3c6573fcc4f1ea3266801557dd3892bdb7c761b4cf", + "dist/2024-04-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz": "0bc1f546fe0cef2b9516231ab608de68d55f72022fbc9ced5101b600e005f8c4", + "dist/2024-04-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz": "993294f2ae5202785ab242c1c6567df9c8ab1ef44ad35748c526b7fe854fb94e", + "dist/2024-04-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz": "210a4f0d208e0c8e13a57fb3b3e6c98ab5f620e4988d10a127ff1424ac1d5ca9", + "dist/2024-04-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz": "f10f7df41a13ee2ecdc25d60e697cba2342129a912ef20d8bfca5f611a9ec97f", + "dist/2024-04-29/clippy-beta-s390x-unknown-linux-gnu.tar.gz": "3e24d2af65f0c9667c9997ce091711b2be48e673de3707cddfd8cda455dfecc7", + "dist/2024-04-29/clippy-beta-s390x-unknown-linux-gnu.tar.xz": "0e7b8fbd0207489e38c78c2ae1aa0df4fcbdd84741aa50a86379e4d7ede286b1", + "dist/2024-04-29/clippy-beta-x86_64-apple-darwin.tar.gz": "9c0c47fd97ce72abcd6126315834c62aa7297fe09d447ee4cefa1eb46a116326", + "dist/2024-04-29/clippy-beta-x86_64-apple-darwin.tar.xz": "49dd65c5340fd804399edfa2402cf255fd9bfce1f4aa7fbb3c193c11bc03f8af", + "dist/2024-04-29/clippy-beta-x86_64-pc-windows-gnu.tar.gz": "6c1c3bdf097a1846ae08b098c555c0c5e9e9b646c744d6bb5a855789196b8bf6", + "dist/2024-04-29/clippy-beta-x86_64-pc-windows-gnu.tar.xz": "0a7319d1062f73af1c8f0efe6ad970d10d02259162c5bc84bb1f3a10f3911bcb", + "dist/2024-04-29/clippy-beta-x86_64-pc-windows-msvc.tar.gz": "52fef3f8a64fa58934a633bd4944e8ba9e15f2c2766d0f302dea1a6523864dab", + "dist/2024-04-29/clippy-beta-x86_64-pc-windows-msvc.tar.xz": "8fdbe7590e62ab68a2e463b14da2595e8c4592744f578a813f64d430ed7db4b6", + "dist/2024-04-29/clippy-beta-x86_64-unknown-freebsd.tar.gz": "509bf535622bd26385184ee0c17e4e27a5061a8aeebf5759f24bd578692b2f5d", + "dist/2024-04-29/clippy-beta-x86_64-unknown-freebsd.tar.xz": "2fcd10ada329ba7633616bebc584dca13f11c465e7cf513e76efeb0c3174486f", + "dist/2024-04-29/clippy-beta-x86_64-unknown-illumos.tar.gz": "ea8cea0d4a2379bcd0693f6174b25bc1f90a016dbe8280159cbb61d859806fb0", + "dist/2024-04-29/clippy-beta-x86_64-unknown-illumos.tar.xz": "5a243df8d1345db6bd18e4386ba628e6d302bce1cc572fb447cca4264fda3ee9", + "dist/2024-04-29/clippy-beta-x86_64-unknown-linux-gnu.tar.gz": "2ee560d3c1e306e103eb06d8e8033cd1489b3f6ff9df3bd8a95e25e977befa27", + "dist/2024-04-29/clippy-beta-x86_64-unknown-linux-gnu.tar.xz": "aaf6e54184a65ad6592bf03955a84ad12b561afd86064b1ac5fa03cf637052f8", + "dist/2024-04-29/clippy-beta-x86_64-unknown-linux-musl.tar.gz": "1b3877424a0a0eb507675a50e9d2c793f00ab85f6f12b1e27f871331070325b8", + "dist/2024-04-29/clippy-beta-x86_64-unknown-linux-musl.tar.xz": "6df5eaae5afb64557ba5c3a53ee3e56dab85455838a6044c7671c1180acfeaf9", + "dist/2024-04-29/clippy-beta-x86_64-unknown-netbsd.tar.gz": "1ac05ed7b607fff8b77ff203a663e9f4f2487779bc25e2dcd454cdf5b7583328", + "dist/2024-04-29/clippy-beta-x86_64-unknown-netbsd.tar.xz": "da502375b3cee8b254ab5999809f522692c2d1d90ea0544ad03c0ca514c65ef4", + "dist/2024-04-29/rust-std-beta-aarch64-apple-darwin.tar.gz": "2fdd35ca3b3e3d6f548f11c93337f5bf2e3c088bc78a79881e6f8e230b38b9a5", + "dist/2024-04-29/rust-std-beta-aarch64-apple-darwin.tar.xz": "bc16b3a1ab6ed69f0121a117c50cbcd201500dae4d72ad0dab148913d04cc529", + "dist/2024-04-29/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "9375c786703c17baae1c2066f8d972ac316bc840e478ecd1b94288a1d428324e", + "dist/2024-04-29/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "50d6818a8dd3ab7a3ddbbd7a062b538d9ff3ceb6eada031d1c22ab1dc7ba512c", + "dist/2024-04-29/rust-std-beta-aarch64-apple-ios.tar.gz": "56c3a01e8fd5c2ed75df811993b0b724709fb5473cc308ac09e7f5644468f751", + "dist/2024-04-29/rust-std-beta-aarch64-apple-ios.tar.xz": "3527d1f2c99c806479fb4b3801335dc921b514f171b82cd252cbbfc9ed30b163", + "dist/2024-04-29/rust-std-beta-aarch64-linux-android.tar.gz": "bf8cae7c66489f1aa27f1dea1b37f0d0ae514a6e21b93ff2dc6400dc88feca03", + "dist/2024-04-29/rust-std-beta-aarch64-linux-android.tar.xz": "46799f0bc1b3c13877f6cb732774cb3b33e0d8a081bfb56d0f877e79482aa1de", + "dist/2024-04-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz": "9f90fadab5104e1d415edf3b4edfaf7222f9f0d55f849851efdec74ffee16f8d", + "dist/2024-04-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz": "87ed6774202b18691bd6884df6944c7e9fe9c944b57a2837e7a7647518bf94e8", + "dist/2024-04-29/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "4a0692ad28f7f130b472ffa4aa766b745ba01fb75aa921f2da6622c9c68750df", + "dist/2024-04-29/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "a3d45962489a1e18a87e567cbbc8d3665f38809d0ad2ef15bcf0ff9fb9f470a4", + "dist/2024-04-29/rust-std-beta-aarch64-unknown-fuchsia.tar.gz": "c724f4eb135f73b9c79618f27a1ab35dc7b9d26ca62ed796accce68f9e747a66", + "dist/2024-04-29/rust-std-beta-aarch64-unknown-fuchsia.tar.xz": "8eab25782d16bcee75f86ecbb826346beb4a7525b220b45b3ba05a567c6d4391", + "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "33ab1f8410edf590570d7468dbe2ebb5a0907125bbc8d360a928dcb355f0d0e6", + "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "d3d870209a55ac96391affaa347c04f48cf98c089ac5056f340b8bb38bcc8e60", + "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "4d2bb72b898c30a2fc8d5d3333c2e99a8e30c15891fab641b6a519dc9f0cb611", + "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "fa343e6b6110fcd0c5dae4287ff1a799de5d7e4a805dbf4e9a034bbaed2bf269", + "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz": "f1ec4139783169fd83e1b0184518ed25d26cee7b21f196deecc74e83a1d78725", + "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz": "d100be2f6f0346c4b1f5b41aec0c13a47426bf4d49127f2341c8332903e4e782", + "dist/2024-04-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "bab6051e1071a58cd126580f6644decf16edb4473fe4be6a34791610d820a294", + "dist/2024-04-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "d9b68f06ff23629063e92dfc42aa3115a858238d368e4b52b35c1ea4491b1402", + "dist/2024-04-29/rust-std-beta-aarch64-unknown-none.tar.gz": "96804c2d9accd3242bdc22dad688b2ccee071952477b9c592f099377aee6c591", + "dist/2024-04-29/rust-std-beta-aarch64-unknown-none.tar.xz": "3fed6812d84bdaf787e85c37e23ba729b81a6d25a2b33fed75320e66e6641c89", + "dist/2024-04-29/rust-std-beta-aarch64-unknown-uefi.tar.gz": "8da5f301bff35fc067ec7cfb878ebfa5607af7dbc276a6b34a77404432c700d2", + "dist/2024-04-29/rust-std-beta-aarch64-unknown-uefi.tar.xz": "80d643189dc9af98b6410a01261ce6ad34b1325f3aebf3ff61fb43f1261b41ff", + "dist/2024-04-29/rust-std-beta-arm-linux-androideabi.tar.gz": "2e86b54b0d1f7fefead11d6383bdc80fe0a7b3ccf58381d2a731e6f1c62926de", + "dist/2024-04-29/rust-std-beta-arm-linux-androideabi.tar.xz": "9831a0270457cad2798b5ae4fe956c257c7e10ce5ad211793dc467577cdec29e", + "dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "f96bc303c0c2be9cf589f00aa63b2cf3fb8585ca9dd8860fe525821bfa1fe19a", + "dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "e57a053b1c2bb6fad93dfaffedce7f48fa292196fc8ba6fd2f0c74dc810a13a9", + "dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "49b2cb2ba5296871b5fac5ad9a74a2891e8b78321078a455ba4a65e003bebd40", + "dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "0f9c15d834a9d282a4018934759f7b48ef3d275e09679a68c5fd1b3f047d02e4", + "dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "e59f92827241e670c1aa92b35235ad12340869d59327fb83084b5f4149acbe06", + "dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "ad1cf96bb1fcceaa016e29e8ad34b4cfd711d2e0bd7cabb9cd7cc28abf64d894", + "dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "14a6d318af85bb9fa5c229e45a88a32a71f44ed02cd90a24bb67921eb64dee41", + "dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "ed6b48502ab9169818bceb300b4e6b4fd63366ad5808b047bf9988dae04c2729", + "dist/2024-04-29/rust-std-beta-armebv7r-none-eabi.tar.gz": "345e8a023be55e3b88a0c2677ea28c7bb4fcc5f3ab707638de76065c7592c2d5", + "dist/2024-04-29/rust-std-beta-armebv7r-none-eabi.tar.xz": "6d9b11d08f2d62611327a893b45ba07c36df11f077250496ab0881eb7ac84c65", + "dist/2024-04-29/rust-std-beta-armebv7r-none-eabihf.tar.gz": "a2ae1bf003a8a12b2ecb6bde9868a978820f184af523f0e4c3fc935edd509423", + "dist/2024-04-29/rust-std-beta-armebv7r-none-eabihf.tar.xz": "3d1dcf8308f9d4590b429f6abbf8f42f04496ab490ccf4ed8c9e381e6d886cae", + "dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "a54106d27e4ce97463e7867ceff9dd22ba456f840ec23229e6909b37d48ad554", + "dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "e6abfaa0905a00efeaee85b9f93793bab93e2cf4e172c9d829c5ba85006c688a", + "dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "cbed18e5dc61fcecb2920affc3890c3b8ae46b7fe5a80b3288689e18d490f3f4", + "dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "2b58bb0dd5cd2c5f7f93f4c6e9135090b931e0ffa27ff9efe2b8ff9fbbb7e48c", + "dist/2024-04-29/rust-std-beta-armv7-linux-androideabi.tar.gz": "6a371c2ececd349dfa76a02563069912fc91577ac4446d36c22f96723d7f5e9f", + "dist/2024-04-29/rust-std-beta-armv7-linux-androideabi.tar.xz": "9325daf41ddab02fa845971c10a5e0538a18c7bea14e66fa0f5f6fb16654c7ae", + "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "7f5ba76cfb7c85333c8dab76fb4ad3f12ddc254b95f9ee07fadb8e1270a4f767", + "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "f853b7f929b7a309ed6c08ff8c57d583ce0ccb19270674fb30e63a873834dc87", + "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "0680005d0a12498b687afc583d4f36bd67d0877cd9d3323bfd2df50d15c27afe", + "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "a494b78fcad01c83df9522d460ac2d35d2d00736a921381f2c611dc516edaa16", + "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "cfa555db31b5470e878b0f53d86617e7342e8bf018fe62cb0271dfe13db95f51", + "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "0a8ccd6d88cbe79a855111fbda45aa1a728de655b6927f3d429d901d2afc6503", + "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "eac53424001c884a540c42f0b68447349ec5d0601a030c060aaed76d54895728", + "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "42d78fca62361ff28db5bc43bb01cef7af5c6f4ab2110fe6170c3dce4707aab8", + "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-ohos.tar.gz": "c88de9f2e667da73177fb9c9309d7f1f467e31c18e3ae50d722c71ec8dd876a4", + "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-ohos.tar.xz": "24b3c04a42d511cdc8c6107b597be38981114f0574eced493d0e90fc748094bc", + "dist/2024-04-29/rust-std-beta-armv7a-none-eabi.tar.gz": "cd4ad182a098c61550265879ccc04733c39110827f7ef62eecfb8c120ae4ece8", + "dist/2024-04-29/rust-std-beta-armv7a-none-eabi.tar.xz": "8499a014dfdf448f474a58f148784c2eef245dc909587d876d2fb9ddc6a4ec3f", + "dist/2024-04-29/rust-std-beta-armv7r-none-eabi.tar.gz": "e8e1870e5b12b3d8643d712efb91eb86b2081284cada4a140c1526692ab183c4", + "dist/2024-04-29/rust-std-beta-armv7r-none-eabi.tar.xz": "d6029121eacc44bd4dcd9ef6dd3cd0d775cb6e9a3d99f3d62d746fcbf8981cab", + "dist/2024-04-29/rust-std-beta-armv7r-none-eabihf.tar.gz": "1e0fc42c3802e205130c01ca90f92d793c1c5427b34da66fe77b97cf67b4a5c1", + "dist/2024-04-29/rust-std-beta-armv7r-none-eabihf.tar.xz": "4c8cfdb11bb686111fa4842d13430c86d9d14ada30e9df334b3777fe899233e0", + "dist/2024-04-29/rust-std-beta-i586-pc-windows-msvc.tar.gz": "ff895c1b39b84587f10903f4be13d275b545e690da6761190d12c01acc25c6d8", + "dist/2024-04-29/rust-std-beta-i586-pc-windows-msvc.tar.xz": "fdcbcff7b740235bb16e44174fff9080a7c0a31be358c8abc41805c02c20c3b2", + "dist/2024-04-29/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "6b227f3b9001e148b66b7001f753a6f88fef9677e39d8fcf4d9c35fe8d345568", + "dist/2024-04-29/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "1e29297beb8de3778ba958731294823d9a93aac1e0d8833abc5aa99e2935965b", + "dist/2024-04-29/rust-std-beta-i586-unknown-linux-musl.tar.gz": "26481ad5f22a319830d42f69b1c0195bd65900ebe112e659432334b3468f3d0e", + "dist/2024-04-29/rust-std-beta-i586-unknown-linux-musl.tar.xz": "c8a837e0d9da8ad976fc1539541c085365aac9dd28b34e4a289d38a823d1b065", + "dist/2024-04-29/rust-std-beta-i686-linux-android.tar.gz": "f05e28a52f17e22f36ffc70018012a1fe6a07f4b461e774b36464f32bc8f8dea", + "dist/2024-04-29/rust-std-beta-i686-linux-android.tar.xz": "f9501b2691c51e54a6f4cc6fb72e41901eb551d3a7be5f82a94ce2d3e217828b", + "dist/2024-04-29/rust-std-beta-i686-pc-windows-gnu.tar.gz": "8d9a782d4f7450bca536aab45147c6ef08bc3847b43fdd171c6449e29762eda0", + "dist/2024-04-29/rust-std-beta-i686-pc-windows-gnu.tar.xz": "4008712e03fb6494eaba3d79051c5e3fdd93d4c52ae8d86cf8f344b5f051cbca", + "dist/2024-04-29/rust-std-beta-i686-pc-windows-gnullvm.tar.gz": "cfb23242e495834a3d0f7ffa3da4a0b206dcae35872b1455b11faeee5511ba5f", + "dist/2024-04-29/rust-std-beta-i686-pc-windows-gnullvm.tar.xz": "95415742c0171945ffc2b67c913ebd1330e29634af238f5ccc843a965340374a", + "dist/2024-04-29/rust-std-beta-i686-pc-windows-msvc.tar.gz": "e9354d69e39ecfac1d2928664d17d73f808256a4076b849171a9667705c0aa08", + "dist/2024-04-29/rust-std-beta-i686-pc-windows-msvc.tar.xz": "a34bb0a91170d84195f35ba52afa4c9be8a2f2706dbeea02bd6e8908e08ac65e", + "dist/2024-04-29/rust-std-beta-i686-unknown-freebsd.tar.gz": "d65f286de399ccc9e9acaf7a4dc4f885357c750231d54a144ba9a59181814f11", + "dist/2024-04-29/rust-std-beta-i686-unknown-freebsd.tar.xz": "4c93a7da70a69b2ebbac01df64af16344e523d16470b29e57237b1d0925f7721", + "dist/2024-04-29/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "1b978bfd1a9234be7ef197c8c98c5a6b625f6fbb7b0fca58695986768bdca176", + "dist/2024-04-29/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "98d4eb5b89a593c8c4f86244c9a7c737d9c18c0168aebe5923b8d9145adcf89a", + "dist/2024-04-29/rust-std-beta-i686-unknown-linux-musl.tar.gz": "dbf9b3c5b54b3eb0727f976f5632c5b0fcb2f90ac7453962d6cef20f7dae4284", + "dist/2024-04-29/rust-std-beta-i686-unknown-linux-musl.tar.xz": "f209ade093753342dda6e710ee832a538dbdaa08a24d606f9a2a1bc59b83da29", + "dist/2024-04-29/rust-std-beta-i686-unknown-uefi.tar.gz": "3c3ca7f34569b2c70c6b223754418a535dd7dfa087ab6e28ed2ec78d20065887", + "dist/2024-04-29/rust-std-beta-i686-unknown-uefi.tar.xz": "72a7cd0f430ab40d80e93f409b8e26a181010ab4bb75d151e829d51ccdcf8c62", + "dist/2024-04-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz": "b7dfa59bb05cf806c87854d6fce5ef0f160697052fdf6e5a0cad121499108608", + "dist/2024-04-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz": "88bc22f68bab3367cdfa91676418ce1ffc0ec002afb32aed7def880bdd4be402", + "dist/2024-04-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz": "d61019048b941064a99d19e46ff3236a88a2e8fcfb963cedd1d9d1c47963c170", + "dist/2024-04-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz": "7474bda08134c676d74afe5263317af3f271963d8ceaa5efbfa1b657f885c572", + "dist/2024-04-29/rust-std-beta-loongarch64-unknown-none.tar.gz": "e089c77d433d838ca02d7531d6f4a1770fb4a0568acbd96c8f43034d76f2990b", + "dist/2024-04-29/rust-std-beta-loongarch64-unknown-none.tar.xz": "364ae6c89c7a930098286e55193d2f5ee3d5ea80b7cca73046e41725f4a8a2f9", + "dist/2024-04-29/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "c17bfad87d16f3a8d26646525dc59a352718db9e7572acb583b68a18cfdc338a", + "dist/2024-04-29/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "f5c4ecef1c08d19ba6fddbd359a0ce94e46888021cae057fce969276026d086c", + "dist/2024-04-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "3e7e13b0d2e804d228e1e3a9dac0205d294ae29dcc37132f15fb1e218861eb39", + "dist/2024-04-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "ea31b7678e6f64c2f9c28a9af120be04ed6f2a25a496e40afbf6e9aa0dd20b60", + "dist/2024-04-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "f0e1b314c3d5ad1676c68c112581dce62fa06ad557cd5f61034e147b064ed270", + "dist/2024-04-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "8ab7bbea6e2f72df1286facc7d306d01809a4dd9f8901dfdec7e50b594658d49", + "dist/2024-04-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "48f6abda1c7dac185858744aa2cdc3513cdfb6552535282ee83cf9c5365573c7", + "dist/2024-04-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "d920d97f15b56ba6ea81e08b3c29dc7f44f5f30b7513c53446edf95843c332af", + "dist/2024-04-29/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "0a198a770f6e6043e923b0ab1a508fd8b190612d0370c33c8dd2c5f63b6f19dd", + "dist/2024-04-29/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "424a93313cfe2d85acf956be3d9ac71ea8e34ee61617a550ad6ff5360e1dff52", + "dist/2024-04-29/rust-std-beta-riscv32im-unknown-none-elf.tar.gz": "2e2b0a8e41f4ea774d665d6248cbc2fdbe3e582206efeb87d250786ebaad0b1a", + "dist/2024-04-29/rust-std-beta-riscv32im-unknown-none-elf.tar.xz": "2da372c091017b7096e473e5c7016a504d2e041e14173d2520086cb43e0a615a", + "dist/2024-04-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "69d3b21403181b2df14243816388169db2466477ec34bcca5693fb017703686c", + "dist/2024-04-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "281b9c20f8641a3d1b349e762b7f713fb0b91da0d21eec798e639e36a0ea3dab", + "dist/2024-04-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz": "dd9bfd3fd8446d35180fe781139dfb4e04dd658b112eb2a749e8f4aea14f0271", + "dist/2024-04-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz": "b1366375e0c5f53da581741dec91972b0c46d7d466052539207e8feaab0ba3ec", + "dist/2024-04-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "7c6650d8cf8abd51547010e8211af3ef3195099ef43a563460ad4780de20ba17", + "dist/2024-04-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "bab46f3c0078ce346de563bb7a248ca92f15dbdc73bf5a3bc520486118442320", + "dist/2024-04-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "01735b4ad5bc0a53087dd0ccaef2cf174b27e45bf4d2e3c15e64f7522f059c63", + "dist/2024-04-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "0bb272c2c235583ed3e9ec151b3bfc601f8cd07822c2fe47a1258b358be507f0", + "dist/2024-04-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "b2c7f8ee0efe6d0812e4b5dd0979f60f105b84d34d4f600ef75f2eacd954893d", + "dist/2024-04-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "0d5301fc553a6911af6643ab7f57b6438bf649ffcd050d486278c0c5fe38eeba", + "dist/2024-04-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "0d1d35ecb88ee717720ad8e74bd5b602fd6011fe321baddb939f3b161e9cd8c5", + "dist/2024-04-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "a5cf0b98596e68e6f72be2e83c61b8aaa19ead42f248ee2408a3b8f4e97a6657", + "dist/2024-04-29/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "629ed749cdae110668ad9ddbc5c61e99e8d400f3dd0981146c3820deadc360f6", + "dist/2024-04-29/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "192819438ed27a565cdb67b51d2f5caeb6ae258de86191d6922574327f132acd", + "dist/2024-04-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "84286f6cf6f00f3c92dc881f64a31e1ec5910102d8d3d4faf6fc7e2ddf1544a7", + "dist/2024-04-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "304b5f876b47dcbb7c3483c49295b822e8ba83234bb568ce67896ae4773ae2fa", + "dist/2024-04-29/rust-std-beta-sparcv9-sun-solaris.tar.gz": "25062159b859e21dda76ca22d4a31d3aba4fcdb0def78bc5b5cf9887c07c1be9", + "dist/2024-04-29/rust-std-beta-sparcv9-sun-solaris.tar.xz": "5d557ee86457f288462603fe53bcc2e092d84faee543659419fa68c1bd88f554", + "dist/2024-04-29/rust-std-beta-thumbv6m-none-eabi.tar.gz": "a9663048aad82ef832b2cf82fa9fb94be047f77e283e8aa3e2df6ad957d0782d", + "dist/2024-04-29/rust-std-beta-thumbv6m-none-eabi.tar.xz": "4c4b703a846b4123d09c1eace6322e82784a004b278f1f3b1ca1279e96207f18", + "dist/2024-04-29/rust-std-beta-thumbv7em-none-eabi.tar.gz": "32907c33f240abb1cb17ac438da42c5fa3932b270ad08fd6914775c5b59a02f5", + "dist/2024-04-29/rust-std-beta-thumbv7em-none-eabi.tar.xz": "112583227d2b6abfef6eeb78d980bf2efef392f3b66e433c4959a642d72ffc7b", + "dist/2024-04-29/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "7ba0084527a18479c4b6f6a0dba8ae23a0ed50e9fc5fbfce23cae1babb5a1e12", + "dist/2024-04-29/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "49eb4e2efe3a76713ce1fecacaf915717eeed8552912b92895c7fee068a85a36", + "dist/2024-04-29/rust-std-beta-thumbv7m-none-eabi.tar.gz": "518a532b52f2dad2825158614cd00b12aac6c6e1983a1ad53e2b0e26d1f1b845", + "dist/2024-04-29/rust-std-beta-thumbv7m-none-eabi.tar.xz": "2895e5796a29fd016462694d880e38eb191cb92c9bdb14414c1d6e63b23d3394", + "dist/2024-04-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "2af590c063344c4c3f65d704fa255232b5f5954872d03c4c55d48662cbe6bb17", + "dist/2024-04-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "a09df5f38183d9fe6116c807619f812410763ddedf06055bfe8040b5794104d3", + "dist/2024-04-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "eac22c4972bde3a57cf2ec4e31b43db3c4b7d961ae31475d8942e898c07640cc", + "dist/2024-04-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "104f2c6490e30cc47833edbd806c2efe6256d1194600b2278339612f94704d45", + "dist/2024-04-29/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "b3c9c9d7ce8c1db6f20e8ede542e67aacd6047c52882a5d06c4f96a40a7304d9", + "dist/2024-04-29/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "76bfb114bc7674792934a4892d2db41fdc8f5bd30c3aa96c43e8055199157476", + "dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "1308335fe80dcafaba511ee589959d461145533de5f76118fee29a7e9a15841f", + "dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "cb8acdb8920983c03b9495cf3506a3014384b4d2f6a53e7907924d38a0baf7f0", + "dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "9dd2e5ce7534ab4fbb93ff652196e877f4e9eea3863920c3d34a05d9a3598c81", + "dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "4b6e962facf7c54846965a8d6880e4a980804459151f2e22ac5af79bc79e26bb", + "dist/2024-04-29/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "731603392b6e3d36b3a4956928d084e293ef18c8b8593efa756e753a2a309709", + "dist/2024-04-29/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "8b681b3af47855eb63c4ffe06a2bc6bc4f365354ffbc171ce8cbd8c2a3588a07", + "dist/2024-04-29/rust-std-beta-wasm32-unknown-unknown.tar.gz": "7b87e59391493c3147c03794061111e25bdae669aea58190a951cdef111e75e0", + "dist/2024-04-29/rust-std-beta-wasm32-unknown-unknown.tar.xz": "d15eaadb101027906c2fce15b95a3f820bdbc4cf145b705bafc2ac5291289c3b", + "dist/2024-04-29/rust-std-beta-wasm32-wasi.tar.gz": "07390ec742b79ec11b2c3ec65f60efe5d7c616f50c33058fce346f6e9ad21af3", + "dist/2024-04-29/rust-std-beta-wasm32-wasi.tar.xz": "79e34d46621c298cadb98c00ce3b25d97474aec300d85255153b47e21b7bb744", + "dist/2024-04-29/rust-std-beta-wasm32-wasip1-threads.tar.gz": "b916dc9051b0278f820ea0b093db3ecae2e27de641ef67a9b508df75dc92c938", + "dist/2024-04-29/rust-std-beta-wasm32-wasip1-threads.tar.xz": "2867922a39da3b02ebdb93fb78b010695daf468f87485ad8ab79c7f3eeb18b11", + "dist/2024-04-29/rust-std-beta-wasm32-wasip1.tar.gz": "792b718c0a72e97ba85a17ba67ee09e55b85de829fe4021f828ce54ff8cb31e0", + "dist/2024-04-29/rust-std-beta-wasm32-wasip1.tar.xz": "abff86499119bddfeda9059004549941dbcd3d911702d4a9c198b94f60e60f4e", + "dist/2024-04-29/rust-std-beta-x86_64-apple-darwin.tar.gz": "0bcc7698efafb42a37f20815f5660e39829a42a2776304e7129d0a4ec0c7520b", + "dist/2024-04-29/rust-std-beta-x86_64-apple-darwin.tar.xz": "c437626e250b0d06c05dc828ab81d0d2c543ffce4b100567910508974ea50045", + "dist/2024-04-29/rust-std-beta-x86_64-apple-ios.tar.gz": "7c98c9f491bfc837111769a45c10ce2f1ef73c22377158ef9ae80b38034892c0", + "dist/2024-04-29/rust-std-beta-x86_64-apple-ios.tar.xz": "f4bda724e6e382e02ddf4e4e7a479120420666a5a1ad3c87a85d4d3c763f2cb2", + "dist/2024-04-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "01efbb2e48045318e18bfc7b6c190b461a219e81fc1cca6c855bf0c658aef556", + "dist/2024-04-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "9bff316c6d2fbb3c0889f9ffe4eae496b293fb3afaf8d597155e6badbf0c6a8e", + "dist/2024-04-29/rust-std-beta-x86_64-linux-android.tar.gz": "5da713547a8af2c86da7db5d8aa4c27188dea1089fded81ffbbeb0f78952a10f", + "dist/2024-04-29/rust-std-beta-x86_64-linux-android.tar.xz": "9d6a45d6af395360c63ce97bcfc2f9a2967c708afcd979f17fa447239703a92b", + "dist/2024-04-29/rust-std-beta-x86_64-pc-solaris.tar.gz": "d1a71110bee002c8edfbcc00e0f5eede5afa005b09944bb2cde469c658049e70", + "dist/2024-04-29/rust-std-beta-x86_64-pc-solaris.tar.xz": "6b8d18c83b9fffdddf9e55c807dc7d5784cc6d7ae90a57c29b87d707f0656964", + "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "28921ee14426f54aa09523547516437130654b2d9814120d286f209666c88533", + "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "7c3125cce30978ca2619e9aab150cb5b9b2535fbb6274d4ac1b1d4342c7b0220", + "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz": "ee5c237f092f8a4ba797c4c7769dfd4da81b5c86d2f4b88704d127642d222a22", + "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz": "30c84b04bd2d4d33abf1875cfee5f227ef6484edc67b3cc4c9c96d92c8406d6f", + "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "81274050e72c5a8ffdead83f7be62434f35a65517a1b3c6f7d9d14d0d59da710", + "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "215e20c78a2a4edf9b8368a29a09af5f4cf8d0edd1995de3bbf2eff01127cab7", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "340131cba121827a9753e19cb3a4b9ba2ebe30569fb20d7f9300b4dbe2a15cf4", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "69626178bc5309afc8a02c941bd77e70e1aa6917ffb6bf0d67a57d921b5c664a", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-fuchsia.tar.gz": "22c6c90533dad3a731ad8a6696e6cdc1b15579e25c658fa2b094185e1893934f", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-fuchsia.tar.xz": "30d7ef6684fa98e28037b69d4220cba40489c23e80fe7793c98b388dc161757d", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-illumos.tar.gz": "9d7192d32eaa6b6ccb0f615da0f4cd80827ba6484eabeaf401d8217678f1e313", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-illumos.tar.xz": "7a3fb35e0bb252d5f90773136d1417c26d5601beadb77d6da6f5ad3081977f07", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "e987635519c1edc8a1d147ca4a86283637e4dbd0a49736b01d605e45a3a14e8f", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "c3ab6b97dccc0038c68494b03b6d444d534e447226a2b2e140af54c94fca0b2d", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "72e8113687be8f947c50befb42b0957dd564f01693cf4d68d749a9e074032ada", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "867b24f33b19f40727c71818c8a002718d44d4cd4ceca44314331e19c1adc1a4", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "f9b0fd9605bd4e264f5303bd740d9a0195bc147132969965b221f9da0d7875bf", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "022dcf4887df41d776ba2666858b9aaab479758134a71f7c6b2172ed7c1a1752", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz": "b5ff4a0ecd7e0f71a9557b6096bb907e5cbc8982431f0d9b01d8e1a895d8b37e", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz": "e40d5bfb46aadf6faf849df548154db3f35f356f8b98037a056802a235922b8a", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "57cfb1fa472dd9c01fc0caf605a55b7248375d616acf84ec12f6430d5e07e2ee", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "e4121f060b917c811d971e85ce02495e83150ddcceb2204615edff24bd55bfa6", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-none.tar.gz": "d63559803c8eb47e0d10d9f3a2284477b570a2536bb541762774271451e1f0ce", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-none.tar.xz": "5388cf8ecaa234d507e505e8c6d433c5de8811b2717aa254e4caac9f4aa6cd97", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-redox.tar.gz": "0f027163f37618df4330ecd82afece432b0a509ab20333d7b787c0d139ea89c2", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-redox.tar.xz": "b1c722e894b145c2183183fa58762c64402fac077419dc7874f8b08eee665651", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-uefi.tar.gz": "24e2ac0d44619ef9b76cb1af6178103d65ab12e2677b366e8aee0604798fe5f1", + "dist/2024-04-29/rust-std-beta-x86_64-unknown-uefi.tar.xz": "1d8a45f1bfe6650edc5ddfc8683190eff5a74384abcb2f73eb3d1e88d566ccfc", + "dist/2024-04-29/rustc-beta-aarch64-apple-darwin.tar.gz": "ea113c567692d54983ab6c376761651b6dcf9bedad5b5d822d28c0d0d0733cf2", + "dist/2024-04-29/rustc-beta-aarch64-apple-darwin.tar.xz": "e36363f1ea531d2fd563f471758e387de37a34e7ef6f4c12175979657333c5b4", + "dist/2024-04-29/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "52d77d540fc3f83d82f35f358ccd9055fb75453af3e3bee4b11636742559db13", + "dist/2024-04-29/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "843c56f5431c1feda85ceaeef0daf988e8ae020b3556326fb1f75ea7968bf2df", + "dist/2024-04-29/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "ba2fe37dda1a487a2c75151895f4f6e886e9476a992272ce26e9b5fd7adb11f9", + "dist/2024-04-29/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "ccb7be3935de1920509d2061d38f92f1fb8d2a5dd6cef392492242a929363fa9", + "dist/2024-04-29/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "40636e0936bd311803317825c5fb6b446cdb5536ada1db097b567df04a86d7dd", + "dist/2024-04-29/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "804ef68f24bc0ba5150177d8b8515daa54aa82fcb61472385ef1a1d897c5c3e1", + "dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "a320c2869d1d2c92b698397d4467c8498cad9481f38d28ac810bd165399ca46b", + "dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "7ce92211d87068d9c223806929adc34ca611a1321cd58b5bd81aabb0ec3ff085", + "dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "79c16b902884301882d16be36fe75ecb32a8e49abde0038ce21cfbee883c2c3a", + "dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "9384eb9bdbb585b414b6c04c592a79e90a0c0ebfeeb970e5e1b920cb638807cc", + "dist/2024-04-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "ff99de5b819a4fb9adce9386a309b9841bd33632eb7d5079415a6ca6fc86b9dd", + "dist/2024-04-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "55635cde13af11dd8cc007d2e0499bfee493bdfba87b6efd7b1fa4115f5728dc", + "dist/2024-04-29/rustc-beta-i686-pc-windows-gnu.tar.gz": "de82ac745275f069225b84574ed145afaf9f54abde5246592e49d5d1cf40cac1", + "dist/2024-04-29/rustc-beta-i686-pc-windows-gnu.tar.xz": "a8a7bf64d33c95a2f94265fba8dd9ac50bbb727f4bc3e79be5bf61212cb5d22b", + "dist/2024-04-29/rustc-beta-i686-pc-windows-msvc.tar.gz": "88967a99c993d6e0c3c7948308510644286ac826266dbd3d89aaa083100711db", + "dist/2024-04-29/rustc-beta-i686-pc-windows-msvc.tar.xz": "1804f75786482946258ff0e827274357c49e90a7f2f568add7353249f2ab78b9", + "dist/2024-04-29/rustc-beta-i686-unknown-linux-gnu.tar.gz": "3cb7e02c61d4a21d8289289b874b25e8b020c1d553e5af950160bffc14f51c18", + "dist/2024-04-29/rustc-beta-i686-unknown-linux-gnu.tar.xz": "2ad4b1311a0e39c359798375912faa91b4e13cd473bd59efd1e4f721777d254f", + "dist/2024-04-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz": "ab19efb741a127615b9022dedf1d895b53c69740cc3da745f9b9888bade9d98b", + "dist/2024-04-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz": "492cc11d54df410c2547890803930fc65950e6b81ced512e24bef56c3e70f3d2", + "dist/2024-04-29/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "c5a631a41f417336f3f65c85adefd1fb0bacc02465485f37d29fc1223c9f6cec", + "dist/2024-04-29/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "0701183b615d9eec9daea724d4cd8fa98dede2260cfb6b137d6cbf8ad6b29a4f", + "dist/2024-04-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "cb70e92d5275862b500614d79eaea3d19319b96798f4850cb19dea9a8038a651", + "dist/2024-04-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "908cbe562d82cca1bf176fdc99af867966ea423d244c4a50e14bad19f6878201", + "dist/2024-04-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "8580a3eb6d6df1774f4b6ca06dc1195c42b1e2a463488a5d851e99b0ca6d0249", + "dist/2024-04-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "2627948036e905f2e280663c56c86c172e2b0d057311ade7ca238953b7e0c36a", + "dist/2024-04-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "526e4f129fdb4b2c8f4317c57105a09ff03e71771d6d6bbbc9380917b5440d71", + "dist/2024-04-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "fd9dcf60838376478d7cc505ec7fc39f86f9d042646a3b836e9c06825927c7eb", + "dist/2024-04-29/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "664c1255a9435d1ad086329a3c215974b9302d481762240cc9d0328d9f1b8c9a", + "dist/2024-04-29/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "a585ce7684e4174f03adb09df17221e1729e8179dbc91b9a0f8813c3ecc0822d", + "dist/2024-04-29/rustc-beta-x86_64-apple-darwin.tar.gz": "59a1d91009b506a5bce3c276993cb8acfd71f73d01f9eaf4195b36114ac822c3", + "dist/2024-04-29/rustc-beta-x86_64-apple-darwin.tar.xz": "f86f3309cf2784b076f14e7da9e921c294a7701ea92d378c609061deccbc6bff", + "dist/2024-04-29/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "f5c074461409b33a9791325d4014e6861ad36f99b9e48e54ecceb73986450be1", + "dist/2024-04-29/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "045431eec6f839b1c40b5a75c5000f80bd6351274a59b29d962833495324ecb6", + "dist/2024-04-29/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "a3abfb68e60544170f47209bbf048f1374e5bb75901a529e2ac2f315758155f8", + "dist/2024-04-29/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "398c41a3219781c7cf1a907406506526b672abca6d3ab59c30556390a5f992c9", + "dist/2024-04-29/rustc-beta-x86_64-unknown-freebsd.tar.gz": "38895e615efd0bf75ca14b0ab0a085527cca64fae17631d1780a8f51acd26d17", + "dist/2024-04-29/rustc-beta-x86_64-unknown-freebsd.tar.xz": "786f40030dbe5e6897aafe4bda44770920b2010b93fc5ce86574774e531e2eff", + "dist/2024-04-29/rustc-beta-x86_64-unknown-illumos.tar.gz": "7003cab7650dae7e3d29032422a57782a2c146024c437a6466ae1dd2b61a6618", + "dist/2024-04-29/rustc-beta-x86_64-unknown-illumos.tar.xz": "bed3cc10203e8bd4d43b6245928c8a607acc5b6e633635caea45eb4eef4bda56", + "dist/2024-04-29/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "84cdea91c9f1e848ea17f554229ca80d18d093fc609641d8f003c4f2d4871866", + "dist/2024-04-29/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "a20fce7512f7c8cc6230a0f63f12855b04370d25e621183f71aa444c90c36b4b", + "dist/2024-04-29/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "87e0c484ade99efab57c655ef96dbabf7a02314540575b65a14372ab5496c36c", + "dist/2024-04-29/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "469757d8f35c9f4210aefd2ba660ee249e4409d47b908a6c68c1e650ee81ae67", + "dist/2024-04-29/rustc-beta-x86_64-unknown-netbsd.tar.gz": "4a38000480fe78fd5da7f9b71d36f296a6ae103254d932c4de6b902354e86bbf", + "dist/2024-04-29/rustc-beta-x86_64-unknown-netbsd.tar.xz": "45945d6af237fe4c91fde7db02ca19e99bac56a911b8db79be9b6ab8bb3934e1", + "dist/2024-04-29/rustc-nightly-aarch64-apple-darwin.tar.gz": "0b07375a9a6507fd4932a05b5aaf28ed349fe2040103f1cb69c8a2494437258f", + "dist/2024-04-29/rustc-nightly-aarch64-apple-darwin.tar.xz": "143bd7ed3ca7b913ddd0cea7cda8d1a0e4c29cc2ccbb7d29f0e45c2a87c3ec46", + "dist/2024-04-29/rustc-nightly-aarch64-pc-windows-msvc.tar.gz": "9404c111b91fd092367b88adbc37dce10a98c443bd8d9e13a860e1fb4e3af96e", + "dist/2024-04-29/rustc-nightly-aarch64-pc-windows-msvc.tar.xz": "f9f432907c276edcae5ad8ade0264f3c03109be02e791a814edc8ad3d229637a", + "dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz": "33425c90427424f0b30fa2a6331a3b59c680f1c1bd0d8845d7e6bc1e2f80292d", + "dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "03792890c64c72f30143849894b15f0eb3d6ad735fceede9092abd900ee733e4", + "dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-musl.tar.gz": "cf6f2bffa0db1b4b9b8e95801bf415dcce413f902e26f4c1831dff1a00752b99", + "dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-musl.tar.xz": "9192fdb668df8d4cab776623db7d01e35af42fea94098c1d4ba53190825d81a8", + "dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz": "a174e7e08da2abc6b84499360670188f5cc61b6d055967e04bf602ff3d831f45", + "dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz": "5a59811027586863852b15fc2b603e7e69b19841f4c10d2527ef1fc5b77d8af2", + "dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz": "645bb5dd7a96bb9292b9956cb9705e9aed2408e47728f245564f1f7404ede783", + "dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz": "1fe34911b082c3a5ca4f24656675c095d2cf56f8005be9ca2517d0ef7d0a2b37", + "dist/2024-04-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "f2d6403d81bb0afe2e14956828987a0bb044c95f2d9566e1d792dd922dad7914", + "dist/2024-04-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "d93fdafcbbfd50c88c3f4feb4c68b053882ccae02c45e1615aeeae5a86f4aa98", + "dist/2024-04-29/rustc-nightly-i686-pc-windows-gnu.tar.gz": "a9e997b03559b3dfa2a0eba6ed7a142d7651ea7f4ba4e788d9de807b50558e58", + "dist/2024-04-29/rustc-nightly-i686-pc-windows-gnu.tar.xz": "4412b5fbfab8c5b31e57cf8c4ce9a9d13cfc9c0a8174ea1fc8a7c05281e1cb54", + "dist/2024-04-29/rustc-nightly-i686-pc-windows-msvc.tar.gz": "1725c41500dbf6bea554f3d4acaba70167f0e89087aaa3eb3c0f8a99047c55c4", + "dist/2024-04-29/rustc-nightly-i686-pc-windows-msvc.tar.xz": "27db022494afebbe05605f134191e8b2e78bfdeaa638d4215174038ca9dd2fd7", + "dist/2024-04-29/rustc-nightly-i686-unknown-linux-gnu.tar.gz": "dc1a05d49b773dba06808c1c50653ecac506b3433f0f6dfa307109a7c621cc1a", + "dist/2024-04-29/rustc-nightly-i686-unknown-linux-gnu.tar.xz": "cc58ce3af8f5481ada4dc129079cd558664717526b2f7f9a02bde6bafb6f45ad", + "dist/2024-04-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz": "34cfe803126ae9218b17adfe833a55c697dfa50729ac83b642529f3682d12d15", + "dist/2024-04-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz": "c752dc8962656c09047151fd24166f3134fbeed85006b5d22496691079c7fb9c", + "dist/2024-04-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz": "386b086b8aad922050c813dd58bb79a52ef806b2d1413e2e9cc46d6e43b81d7c", + "dist/2024-04-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz": "d9eec9ab7c265444ac5f04d4ec9e77d4c0c3c2e34c5804db8abf5f94c8fd2272", + "dist/2024-04-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz": "91df129046443554bfb836d25886aa9807b917acbc9dcf30f6531cde7bf912fa", + "dist/2024-04-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz": "ca9b574b9f2e914b5a6d9e011aba805d1e6f9b687dc1a1868e88f0e4d9e4401c", + "dist/2024-04-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "8b44f96a1ccd6d501b0af3960edb2c1a6c93957676a1c2cdb831e614de398f8b", + "dist/2024-04-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "f8a10a6767b80bf24f73223b9e46e1b18b6bf6746ad2115eb8968a0e482f0e4e", + "dist/2024-04-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "a197208807503a9cfbc6df938d614a192da48884b2e4892f7b1d234579091be1", + "dist/2024-04-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "af3a1a33942bd8a3417593dc118abb1db0373f5410f54771713c05bb86724fed", + "dist/2024-04-29/rustc-nightly-s390x-unknown-linux-gnu.tar.gz": "5a3a3aa73b6a0f21c63b9a40bdbd0bb4dc59bd75add0a06e292ced791fad31be", + "dist/2024-04-29/rustc-nightly-s390x-unknown-linux-gnu.tar.xz": "6d7903f1c9fc95a23448717326d667dce59e54aaff821443d3cd9137cf3537fb", + "dist/2024-04-29/rustc-nightly-x86_64-apple-darwin.tar.gz": "64eede54da4bf88b0a42ecf7f7a4bf8002b5550e60a64e1e48244c7f5b04768c", + "dist/2024-04-29/rustc-nightly-x86_64-apple-darwin.tar.xz": "0a8f95e3bb0bebf9bcc8116b91bab3ba97cb6ff4021713586280aaceed9da030", + "dist/2024-04-29/rustc-nightly-x86_64-pc-windows-gnu.tar.gz": "58f9e0dd9c1aadde2dfd869528adadd4acc29ab0850236f3cee5f023d4211939", + "dist/2024-04-29/rustc-nightly-x86_64-pc-windows-gnu.tar.xz": "a211a962093e0d09358d51a6eb48da0966a02383c6b00c8acc077b5663d7d707", + "dist/2024-04-29/rustc-nightly-x86_64-pc-windows-msvc.tar.gz": "5631926874dc54204c319137a77a89de5e6f408de2a832109e2be71ea79f27d1", + "dist/2024-04-29/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "a8cf87bc663b5e3dbcc97b0eb58bb1b9b5b0100aacb47dc0c372fe1612517244", + "dist/2024-04-29/rustc-nightly-x86_64-unknown-freebsd.tar.gz": "1011f98197a9fe82d6095f4521934a06eea5f7e9719a6e4c9e3bf13d68f799ca", + "dist/2024-04-29/rustc-nightly-x86_64-unknown-freebsd.tar.xz": "79599b3f91f9372262e97a417f4e104ef5192c0f6f8df204aea9c8b3ee39430e", + "dist/2024-04-29/rustc-nightly-x86_64-unknown-illumos.tar.gz": "7179a453bdcb17e401c0af8f4ab86cb5a4752a8ec80b0cbdd4cf1854c7f36a35", + "dist/2024-04-29/rustc-nightly-x86_64-unknown-illumos.tar.xz": "d565fc366fdbc305fbfe59e72b971c58f201d69e03a9ffa667d2ca0735cdb7f3", + "dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz": "ae6bd8e20560d48519290d78e3d21f84b983403ca1f8f466a85496276d7866da", + "dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "c7c0f8f44b0275456a27952178caa04c32eb9a1507056ddc05926a0730e17359", + "dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-musl.tar.gz": "3246797ddbc9118de819b13b005b83748338f3c825a7436ebd5aa79ca55539c0", + "dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-musl.tar.xz": "c7e784e77dbabedad88d24d2ae6dc4abb68bc04b1cd6c9d45f6dc28b6d0e2edc", + "dist/2024-04-29/rustc-nightly-x86_64-unknown-netbsd.tar.gz": "c9452de4b3f15f0cf0b7d737b217b2cc7b88a96543bd8ce587ee14be1e21a90a", + "dist/2024-04-29/rustc-nightly-x86_64-unknown-netbsd.tar.xz": "de9b05278a5c69d53ccbb31223526ea2aa2275c0fb3f046d1c1b4d67c0b0c275", + "dist/2024-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "3734353a58dbf6c3831cc6b4ea606357140c191c89e8dfca1d7aa2f3fb8ac53d", + "dist/2024-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "e5e3a6e609fbfd537aa4acfefd3681d4b6c8029e2801a1ef23e8b09cf5a47bfe", + "dist/2024-04-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "22f54857e01d759301d099b67547cdc485596499088d0d749d38058c28e0f752", + "dist/2024-04-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "db48a9d45dc7c7aad4c9bb0d20789dd35fb6ef7a966948c44fbbae132de4c16b", + "dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "fa5d1fb9f3627e7d59269a1f8008d780c685ea04975473f1808287134e7bc5a7", + "dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "61ab625b47fa9097af90a79a1e75a2f2492a415f4009c9043cf453bd4128f031", + "dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "cc79969341fc60991059d0e3f13a69489c1e0915ea5787a88b8605ed5b7f3cd0", + "dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "bbdb75f922b4b1716b033d91c76c4c0aa53061d6e7fa53a9bf16fe076814bbb2", + "dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "13ca68afc3f3970a37951504664b58035102e1ae06d10a744389603b2f7499f5", + "dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "04b174aa724945b6359a555892506c6a742a7c427464e8206433bb3f9a65fc02", + "dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "430333380a590a9de211c8d735989fedb89321cf9f5f9a0b1ef651ec8b598691", + "dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "924713e648806945cd56e54d4c11dc74b65241c8dbf6cc7b401c5c93d0f7ffdb", + "dist/2024-04-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "bb6e5a8b5cc88099e613aa5f4d926165976d8e4a7fccbecf4ac3b0eb966d7a0f", + "dist/2024-04-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "34d5e970304e1734aacb26c095e926c27a07e1a41fe70db9fa2997bef97ad3ec", + "dist/2024-04-29/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "835447a1d9d60659e99903275f327641809fc0148f35149f980d1a17ff87cc9a", + "dist/2024-04-29/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "ddd84a7f900aa239f93711f7da71e57aaedeeba2c9c8a8f23608acc7e48613c0", + "dist/2024-04-29/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "02f0af2bdae167c6091099a9b54ceb150c22b0f20dc861587a02cac78deb0b39", + "dist/2024-04-29/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "822f78f39dcbe3282bf7888a8cdae04efe7b023ded026a7e7f430e4ff15e7942", + "dist/2024-04-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "68a6189652c11a2c142c5339e2f5fb09d5f3e85d860bff063f62d5d3a3d111bf", + "dist/2024-04-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "6740ea882effa2fb87dd72744c08888ce5ec59c9797c00369156b24847bb180e", + "dist/2024-04-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz": "0bb365e2d895ef3c39c4899a01187a23f9b7c5195c30bf845da3917f62f5eafd", + "dist/2024-04-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz": "2e54c9887bc6ed1eb09b9f69c8425da843ea12bf33248fa0ccdc0d14387c1c57", + "dist/2024-04-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "b0c0fe437921d17e2f50cbff87beeac067efa3d5211a241fb6f4c10b8ab500ac", + "dist/2024-04-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "64e7282c0cf4a714b11eed1d28be3a64ba0ccc6d899211a872a5a7809d514c08", + "dist/2024-04-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "100cfde057c81460b8cfde2047fe83ddde360a6df1ff178da5a968b17ecc9df8", + "dist/2024-04-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "38e8712e98fa0bc6962ab2fd2e3b96a2a5dcaa6c16161d8caf71131a1ca5031e", + "dist/2024-04-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "4dab52b50e19348fb39fdad39ab44189c27c10f80b5fbe2cc4723b644611fa87", + "dist/2024-04-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "36d1b2c9150fafc5976c296200ba3fac3e923df3e6f18032068200e2a887146c", + "dist/2024-04-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "7cb4a536320c23d305ce3bd3b7a954d951bf4d358ef3732be75b9b290c4818a5", + "dist/2024-04-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "ede1afc7dc5892ef6f780e987737e145c4b4d00495da8c2e9902182a3a174e20", + "dist/2024-04-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "e2d2d561cbfa0add0e5349682976216d3a7cff4094372c1ed26854bb4e4d93fd", + "dist/2024-04-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "e0380e65e83e4131f6aa7ee4e185689add4372b0c1653312e2ffd56072fdd0fe", + "dist/2024-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "73a140c7ed9c80f209ff976c63b0a34d625d651553c38692c91f048f4e0ae470", + "dist/2024-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "9946b7120465181e05916b8023bc075b32bd85cf45a3b1d8bfba2f94ac78d927", + "dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "eda273f27714b1e45adcc2388149f48de0e32a9104db0b9d1a02f6d37de43fef", + "dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "f2955a4b696d050c219a96c093162b42a2fab921f9f3cb7570f8462928306c6d", + "dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "ec900cc2d3c6d45ef039653f4418f9b9a4a5fddd5d7e8077c3fb08b36c539a28", + "dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "04e6999a3405acc79f5fdcafeeab52880e5eeeedd3909b5f3c57e7647c86ef99", + "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "0730c5ebd576fec5371085f9fac0adde9424e1d7626456ed33bc66351b0ad307", + "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "90cbd84b8d48f0235a1954166f5edd53dc3031532ec6dfcb364f9a9624c9ce11", + "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "5f5c62d321db27eb495f6ea312ef8bea0bf17a7a501a44e062986c416951700f", + "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "a3bf64e2f22436e4484fc818f69d2f750fddd05a96463fd4abfcf655edce36b9", + "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "a847a6f9c7a3ce71c7cd8d81bdfcfcd8e4d128aa28ba0dafea89b0cc37c6c36c", + "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "21fa794456566c64d08f629a385f89b3cfe9d9b69f317ae85fbe7425419108ff", + "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "b3f792f10a98993b4b55d1df951727a4422102d51b1145e51824268d48587ad0", + "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "d791f0ec3c004e7baa0381962bf8ca2f18a3c861152702de5301d0149260e7fa", + "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "9807b2887e976d29f0c04484f8459175b4f6b70ef000037cdc4dada48e3cbd74", + "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "019920d64778af62879e2146c2c13d9f6e2165a38bbfa1982694bfb48864d308" } } From 42ecde4e5f1b9067939663a77acf85fcc36199d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Wed, 1 May 2024 19:22:28 +0000 Subject: [PATCH 224/279] run-make-support: preserve tooks.mk behavior for EXTRACXXFLAGS --- src/tools/run-make-support/src/cc.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tools/run-make-support/src/cc.rs b/src/tools/run-make-support/src/cc.rs index a2d51902652b..146123793be4 100644 --- a/src/tools/run-make-support/src/cc.rs +++ b/src/tools/run-make-support/src/cc.rs @@ -161,8 +161,9 @@ pub fn extra_cxx_flags() -> Vec<&'static str> { if is_windows() { if is_msvc() { vec![] } else { vec!["-lstdc++"] } } else { - match uname() { - n if n.contains("Darwin") => vec!["-lc++"], + match &uname()[..] { + "Darwin" => vec!["-lc++"], + "FreeBSD" | "SunOS" | "OpenBSD" => vec![], _ => vec!["-lstdc++"], } } From ff0bfea45f8e2f9f3081bd416b4610511b9a6384 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sun, 14 Apr 2024 18:06:59 +0000 Subject: [PATCH 225/279] Convert `if` to `match` --- compiler/rustc_hir_typeck/src/fallback.rs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index c0b3984e3e17..3b00c7353e58 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -436,17 +436,12 @@ impl<'tcx> FnCtxt<'_, 'tcx> { // // In practice currently the two ways that this happens is // coercion and subtyping. - let (a, b) = if let ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) = atom { - (a, b) - } else if let ty::PredicateKind::Subtype(ty::SubtypePredicate { - a_is_expected: _, - a, - b, - }) = atom - { - (a, b) - } else { - return None; + let (a, b) = match atom { + ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => (a, b), + ty::PredicateKind::Subtype(ty::SubtypePredicate { a_is_expected: _, a, b }) => { + (a, b) + } + _ => return None, }; let a_vid = self.root_vid(a)?; From aa0a916c81936ba725b7efb68804a4217b09b43a Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sun, 14 Apr 2024 18:07:40 +0000 Subject: [PATCH 226/279] Add a lint against never type fallback affecting unsafe code --- compiler/rustc_hir_typeck/messages.ftl | 4 + compiler/rustc_hir_typeck/src/errors.rs | 6 +- compiler/rustc_hir_typeck/src/fallback.rs | 135 ++++++++++++++++-- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 4 +- compiler/rustc_lint_defs/src/builtin.rs | 44 ++++++ ...never-type-fallback-flowing-into-unsafe.rs | 35 +++++ ...r-type-fallback-flowing-into-unsafe.stderr | 23 +++ 7 files changed, 241 insertions(+), 10 deletions(-) create mode 100644 tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs create mode 100644 tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 07b4948872dd..0caebf44a193 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -99,6 +99,10 @@ hir_typeck_lossy_provenance_ptr2int = hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}` +hir_typeck_never_type_fallback_flowing_into_unsafe = + never type fallback affects this call to an `unsafe` function + .help = specify the type explicitly + hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method -> [true] {""} *[other] {" "}in the current scope diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 1c4d5657b171..fcad88f829e2 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -164,6 +164,11 @@ pub struct MissingParenthesesInRange { pub add_missing_parentheses: Option, } +#[derive(LintDiagnostic)] +#[diag(hir_typeck_never_type_fallback_flowing_into_unsafe)] +#[help] +pub struct NeverTypeFallbackFlowingIntoUnsafe {} + #[derive(Subdiagnostic)] #[multipart_suggestion( hir_typeck_add_missing_parentheses_in_range, @@ -632,7 +637,6 @@ pub enum SuggestBoxingForReturnImplTrait { ends: Vec, }, } - #[derive(LintDiagnostic)] #[diag(hir_typeck_dereferencing_mut_binding)] pub struct DereferencingMutBinding { diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 3b00c7353e58..86a75aa4d787 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -1,10 +1,15 @@ -use crate::FnCtxt; +use std::cell::OnceCell; + +use crate::{errors, FnCtxt}; use rustc_data_structures::{ graph::{self, iterate::DepthFirstSearch, vec_graph::VecGraph}, unord::{UnordBag, UnordMap, UnordSet}, }; +use rustc_hir::HirId; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable}; +use rustc_session::lint; +use rustc_span::Span; use rustc_span::DUMMY_SP; #[derive(Copy, Clone)] @@ -335,6 +340,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { // reach a member of N. If so, it falls back to `()`. Else // `!`. let mut diverging_fallback = UnordMap::with_capacity(diverging_vids.len()); + let unsafe_infer_vars = OnceCell::new(); for &diverging_vid in &diverging_vids { let diverging_ty = Ty::new_var(self.tcx, diverging_vid); let root_vid = self.root_var(diverging_vid); @@ -354,11 +360,35 @@ impl<'tcx> FnCtxt<'_, 'tcx> { output: infer_var_infos.items().any(|info| info.output), }; + let mut fallback_to = |ty| { + let unsafe_infer_vars = unsafe_infer_vars.get_or_init(|| { + let unsafe_infer_vars = compute_unsafe_infer_vars(self.root_ctxt, self.body_id); + debug!(?unsafe_infer_vars); + unsafe_infer_vars + }); + + let affected_unsafe_infer_vars = + graph::depth_first_search_as_undirected(&coercion_graph, root_vid) + .filter_map(|x| unsafe_infer_vars.get(&x).copied()) + .collect::>(); + + for (hir_id, span) in affected_unsafe_infer_vars { + self.tcx.emit_node_span_lint( + lint::builtin::NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE, + hir_id, + span, + errors::NeverTypeFallbackFlowingIntoUnsafe {}, + ); + } + + diverging_fallback.insert(diverging_ty, ty); + }; + use DivergingFallbackBehavior::*; match behavior { FallbackToUnit => { debug!("fallback to () - legacy: {:?}", diverging_vid); - diverging_fallback.insert(diverging_ty, self.tcx.types.unit); + fallback_to(self.tcx.types.unit); } FallbackToNiko => { if found_infer_var_info.self_in_trait && found_infer_var_info.output { @@ -387,13 +417,13 @@ impl<'tcx> FnCtxt<'_, 'tcx> { // set, see the relationship finding module in // compiler/rustc_trait_selection/src/traits/relationships.rs. debug!("fallback to () - found trait and projection: {:?}", diverging_vid); - diverging_fallback.insert(diverging_ty, self.tcx.types.unit); + fallback_to(self.tcx.types.unit); } else if can_reach_non_diverging { debug!("fallback to () - reached non-diverging: {:?}", diverging_vid); - diverging_fallback.insert(diverging_ty, self.tcx.types.unit); + fallback_to(self.tcx.types.unit); } else { debug!("fallback to ! - all diverging: {:?}", diverging_vid); - diverging_fallback.insert(diverging_ty, self.tcx.types.never); + fallback_to(self.tcx.types.never); } } FallbackToNever => { @@ -401,7 +431,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { "fallback to ! - `rustc_never_type_mode = \"fallback_to_never\")`: {:?}", diverging_vid ); - diverging_fallback.insert(diverging_ty, self.tcx.types.never); + fallback_to(self.tcx.types.never); } NoFallback => { debug!( @@ -417,7 +447,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { /// Returns a graph whose nodes are (unresolved) inference variables and where /// an edge `?A -> ?B` indicates that the variable `?A` is coerced to `?B`. - fn create_coercion_graph(&self) -> VecGraph { + fn create_coercion_graph(&self) -> VecGraph { let pending_obligations = self.fulfillment_cx.borrow_mut().pending_obligations(); debug!("create_coercion_graph: pending_obligations={:?}", pending_obligations); let coercion_edges: Vec<(ty::TyVid, ty::TyVid)> = pending_obligations @@ -451,6 +481,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { .collect(); debug!("create_coercion_graph: coercion_edges={:?}", coercion_edges); let num_ty_vars = self.num_ty_vars(); + VecGraph::new(num_ty_vars, coercion_edges) } @@ -459,3 +490,91 @@ impl<'tcx> FnCtxt<'_, 'tcx> { Some(self.root_var(self.shallow_resolve(ty).ty_vid()?)) } } + +/// Finds all type variables which are passed to an `unsafe` function. +/// +/// For example, for this function `f`: +/// ```ignore (demonstrative) +/// fn f() { +/// unsafe { +/// let x /* ?X */ = core::mem::zeroed(); +/// // ^^^^^^^^^^^^^^^^^^^ -- hir_id, span +/// +/// let y = core::mem::zeroed::>(); +/// // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- hir_id, span +/// } +/// } +/// ``` +/// +/// Will return `{ id(?X) -> (hir_id, span) }` +fn compute_unsafe_infer_vars<'a, 'tcx>( + root_ctxt: &'a crate::TypeckRootCtxt<'tcx>, + body_id: rustc_span::def_id::LocalDefId, +) -> UnordMap { + use rustc_hir as hir; + + let tcx = root_ctxt.infcx.tcx; + let body_id = tcx.hir().maybe_body_owned_by(body_id).unwrap(); + let body = tcx.hir().body(body_id); + let mut res = <_>::default(); + + struct UnsafeInferVarsVisitor<'a, 'tcx, 'r> { + root_ctxt: &'a crate::TypeckRootCtxt<'tcx>, + res: &'r mut UnordMap, + } + + use hir::intravisit::Visitor; + impl hir::intravisit::Visitor<'_> for UnsafeInferVarsVisitor<'_, '_, '_> { + fn visit_expr(&mut self, ex: &'_ hir::Expr<'_>) { + // FIXME: method calls + if let hir::ExprKind::Call(func, ..) = ex.kind { + let typeck_results = self.root_ctxt.typeck_results.borrow(); + + let func_ty = typeck_results.expr_ty(func); + + // `is_fn` is required to ignore closures (which can't be unsafe) + if func_ty.is_fn() + && let sig = func_ty.fn_sig(self.root_ctxt.infcx.tcx) + && let hir::Unsafety::Unsafe = sig.unsafety() + { + let mut collector = + InferVarCollector { hir_id: ex.hir_id, call_span: ex.span, res: self.res }; + + // Collect generic arguments of the function which are inference variables + typeck_results + .node_args(ex.hir_id) + .types() + .for_each(|t| t.visit_with(&mut collector)); + + // Also check the return type, for cases like `(unsafe_fn::<_> as unsafe fn() -> _)()` + sig.output().visit_with(&mut collector); + } + } + + hir::intravisit::walk_expr(self, ex); + } + } + + struct InferVarCollector<'r> { + hir_id: HirId, + call_span: Span, + res: &'r mut UnordMap, + } + + impl<'tcx> ty::TypeVisitor> for InferVarCollector<'_> { + fn visit_ty(&mut self, t: Ty<'tcx>) { + if let Some(vid) = t.ty_vid() { + self.res.insert(vid, (self.hir_id, self.call_span)); + } else { + use ty::TypeSuperVisitable as _; + t.super_visit_with(self) + } + } + } + + UnsafeInferVarsVisitor { root_ctxt, res: &mut res }.visit_expr(&body.value); + + debug!(?res, "collected the following unsafe vars for {body_id:?}"); + + res +} diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 2f96cf9e373c..794b854ca5f9 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -5,12 +5,14 @@ mod checks; mod inspect_obligations; mod suggestions; +use rustc_errors::ErrorGuaranteed; + use crate::coercion::DynamicCoerceMany; use crate::fallback::DivergingFallbackBehavior; use crate::fn_ctxt::checks::DivergingBlockBehavior; use crate::{CoroutineTypes, Diverges, EnclosingBreakables, TypeckRootCtxt}; use hir::def_id::CRATE_DEF_ID; -use rustc_errors::{DiagCtxt, ErrorGuaranteed}; +use rustc_errors::DiagCtxt; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 86a0f33a8d15..664c63da0fc1 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -69,6 +69,7 @@ declare_lint_pass! { MISSING_FRAGMENT_SPECIFIER, MUST_NOT_SUSPEND, NAMED_ARGUMENTS_USED_POSITIONALLY, + NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE, NON_CONTIGUOUS_RANGE_ENDPOINTS, NON_EXHAUSTIVE_OMITTED_PATTERNS, ORDER_DEPENDENT_TRAIT_OBJECTS, @@ -4245,6 +4246,49 @@ declare_lint! { "named arguments in format used positionally" } +declare_lint! { + /// The `never_type_fallback_flowing_into_unsafe` lint detects cases where never type fallback + /// affects unsafe function calls. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// #![deny(never_type_fallback_flowing_into_unsafe)] + /// fn main() { + /// if true { + /// // return has type `!` (never) which, is some cases, causes never type fallback + /// return + /// } else { + /// // `zeroed` is an unsafe function, which returns an unbounded type + /// unsafe { std::mem::zeroed() } + /// }; + /// // depending on the fallback, `zeroed` may create `()` (which is completely sound), + /// // or `!` (which is instant undefined behavior) + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Due to historic reasons never type fallback were `()`, meaning that `!` got spontaneously + /// coerced to `()`. There are plans to change that, but they may make the code such as above + /// unsound. Instead of depending on the fallback, you should specify the type explicitly: + /// ``` + /// if true { + /// return + /// } else { + /// // type is explicitly specified, fallback can't hurt us no more + /// unsafe { std::mem::zeroed::<()>() } + /// }; + /// ``` + /// + /// See [Tracking Issue for making `!` fall back to `!`](https://github.com/rust-lang/rust/issues/123748). + pub NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE, + Warn, + "never type fallback affecting unsafe function calls" +} + declare_lint! { /// The `byte_slice_in_packed_struct_with_derive` lint detects cases where a byte slice field /// (`[u8]`) or string slice field (`str`) is used in a `packed` struct that derives one or diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs new file mode 100644 index 000000000000..f13e20cc0f2f --- /dev/null +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs @@ -0,0 +1,35 @@ +//@ check-pass +use std::mem; + +fn main() { + if false { + unsafe { mem::zeroed() } + //~^ warn: never type fallback affects this call to an `unsafe` function + } else { + return; + }; + + // no ; -> type is inferred without fallback + if true { unsafe { mem::zeroed() } } else { return } +} + +// Minimization of the famous `objc` crate issue +fn _objc() { + pub unsafe fn send_message() -> Result { + Ok(unsafe { core::mem::zeroed() }) + } + + macro_rules! msg_send { + () => { + match send_message::<_ /* ?0 */>() { + //~^ warn: never type fallback affects this call to an `unsafe` function + Ok(x) => x, + Err(_) => loop {}, + } + }; + } + + unsafe { + msg_send!(); + } +} diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr new file mode 100644 index 000000000000..1610804c29b9 --- /dev/null +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr @@ -0,0 +1,23 @@ +warning: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:6:18 + | +LL | unsafe { mem::zeroed() } + | ^^^^^^^^^^^^^ + | + = help: specify the type explicitly + = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default + +warning: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:24:19 + | +LL | match send_message::<_ /* ?0 */>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | msg_send!(); + | ----------- in this macro invocation + | + = help: specify the type explicitly + = note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: 2 warnings emitted + From b63cb6fd81e6d58af308ede0241ecf7563d4723c Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 19 Apr 2024 17:33:55 +0000 Subject: [PATCH 227/279] Add an explanation about never type fallback --- compiler/rustc_lint_defs/src/builtin.rs | 40 +++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 664c63da0fc1..c7996c27c2f0 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4250,13 +4250,46 @@ declare_lint! { /// The `never_type_fallback_flowing_into_unsafe` lint detects cases where never type fallback /// affects unsafe function calls. /// + /// ### Never type fallback + /// + /// When the compiler sees a value of type [`!`] it implicitly inserts a coercion (if possible), + /// to allow type check to infer any type: + /// + /// ```ignore (illustrative-and-has-placeholders) + /// // this + /// let x: u8 = panic!(); + /// + /// // is (essentially) turned by the compiler into + /// let x: u8 = absurd(panic!()); + /// + /// // where absurd is a function with the following signature + /// // (it's sound, because `!` always marks unreachable code): + /// fn absurd(_: !) -> T { ... } + // FIXME: use `core::convert::absurd` here instead, once it's merged + /// ``` + /// + /// While it's convenient to be able to use non-diverging code in one of the branches (like + /// `if a { b } else { return }`) this could lead to compilation errors: + /// + /// ```compile_fail + /// // this + /// { panic!() }; + /// + /// // gets turned into this + /// { absurd(panic!()) }; // error: can't infer the type of `absurd` + /// ``` + /// + /// To prevent such errors, compiler remembers where it inserted `absurd` calls, and if it + /// can't infer their type, it sets the type to fallback. `{ absurd::(panic!()) };`. + /// This is what is known as "never type fallback". + /// /// ### Example /// /// ```rust,compile_fail /// #![deny(never_type_fallback_flowing_into_unsafe)] /// fn main() { /// if true { - /// // return has type `!` (never) which, is some cases, causes never type fallback + /// // return has type `!` which, is some cases, causes never type fallback /// return /// } else { /// // `zeroed` is an unsafe function, which returns an unbounded type @@ -4271,7 +4304,7 @@ declare_lint! { /// /// ### Explanation /// - /// Due to historic reasons never type fallback were `()`, meaning that `!` got spontaneously + /// Due to historic reasons never type fallback was `()`, meaning that `!` got spontaneously /// coerced to `()`. There are plans to change that, but they may make the code such as above /// unsound. Instead of depending on the fallback, you should specify the type explicitly: /// ``` @@ -4284,6 +4317,9 @@ declare_lint! { /// ``` /// /// See [Tracking Issue for making `!` fall back to `!`](https://github.com/rust-lang/rust/issues/123748). + /// + /// [`!`]: https://doc.rust-lang.org/core/primitive.never.html + /// [`()`]: https://doc.rust-lang.org/core/primitive.unit.html pub NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE, Warn, "never type fallback affecting unsafe function calls" From fe9c5e651092786565b077841f69fa5559701ae5 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Sun, 28 Apr 2024 19:26:23 +0200 Subject: [PATCH 228/279] Reorganize `use`s --- compiler/rustc_hir_typeck/src/fallback.rs | 24 +++++++++++------------ 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 86a75aa4d787..52ece8887b97 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -1,16 +1,18 @@ use std::cell::OnceCell; -use crate::{errors, FnCtxt}; +use crate::{errors, FnCtxt, TypeckRootCtxt}; use rustc_data_structures::{ graph::{self, iterate::DepthFirstSearch, vec_graph::VecGraph}, unord::{UnordBag, UnordMap, UnordSet}, }; +use rustc_hir as hir; +use rustc_hir::intravisit::Visitor; use rustc_hir::HirId; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; use rustc_session::lint; -use rustc_span::Span; use rustc_span::DUMMY_SP; +use rustc_span::{def_id::LocalDefId, Span}; #[derive(Copy, Clone)] pub enum DivergingFallbackBehavior { @@ -508,23 +510,20 @@ impl<'tcx> FnCtxt<'_, 'tcx> { /// /// Will return `{ id(?X) -> (hir_id, span) }` fn compute_unsafe_infer_vars<'a, 'tcx>( - root_ctxt: &'a crate::TypeckRootCtxt<'tcx>, - body_id: rustc_span::def_id::LocalDefId, + root_ctxt: &'a TypeckRootCtxt<'tcx>, + body_id: LocalDefId, ) -> UnordMap { - use rustc_hir as hir; - let tcx = root_ctxt.infcx.tcx; - let body_id = tcx.hir().maybe_body_owned_by(body_id).unwrap(); + let body_id = tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner"); let body = tcx.hir().body(body_id); - let mut res = <_>::default(); + let mut res = UnordMap::default(); struct UnsafeInferVarsVisitor<'a, 'tcx, 'r> { - root_ctxt: &'a crate::TypeckRootCtxt<'tcx>, + root_ctxt: &'a TypeckRootCtxt<'tcx>, res: &'r mut UnordMap, } - use hir::intravisit::Visitor; - impl hir::intravisit::Visitor<'_> for UnsafeInferVarsVisitor<'_, '_, '_> { + impl Visitor<'_> for UnsafeInferVarsVisitor<'_, '_, '_> { fn visit_expr(&mut self, ex: &'_ hir::Expr<'_>) { // FIXME: method calls if let hir::ExprKind::Call(func, ..) = ex.kind { @@ -566,7 +565,6 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( if let Some(vid) = t.ty_vid() { self.res.insert(vid, (self.hir_id, self.call_span)); } else { - use ty::TypeSuperVisitable as _; t.super_visit_with(self) } } From 3c815a644cd1f9139efe960c0d2ba3accdc4092b Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Mon, 29 Apr 2024 01:53:54 +0200 Subject: [PATCH 229/279] Add `UnordMap::try_insert` --- compiler/rustc_data_structures/src/lib.rs | 1 + compiler/rustc_data_structures/src/unord.rs | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 0c322939db97..cf54e700e2b9 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -25,6 +25,7 @@ #![feature(lazy_cell)] #![feature(lint_reasons)] #![feature(macro_metavar_expr)] +#![feature(map_try_insert)] #![feature(maybe_uninit_uninit_array)] #![feature(min_specialization)] #![feature(negative_impls)] diff --git a/compiler/rustc_data_structures/src/unord.rs b/compiler/rustc_data_structures/src/unord.rs index ca66d58c1395..1ccd22a56c95 100644 --- a/compiler/rustc_data_structures/src/unord.rs +++ b/compiler/rustc_data_structures/src/unord.rs @@ -4,6 +4,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; use rustc_macros::{Decodable_Generic, Encodable_Generic}; +use std::collections::hash_map::OccupiedError; use std::{ borrow::{Borrow, BorrowMut}, collections::hash_map::Entry, @@ -469,6 +470,11 @@ impl UnordMap { self.inner.insert(k, v) } + #[inline] + pub fn try_insert(&mut self, k: K, v: V) -> Result<&mut V, OccupiedError<'_, K, V>> { + self.inner.try_insert(k, v) + } + #[inline] pub fn contains_key(&self, k: &Q) -> bool where From 0df43db50c8afac0e6406a92721b1c669b882c03 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Mon, 29 Apr 2024 01:54:16 +0200 Subject: [PATCH 230/279] Add proper support for all kinds of unsafe ops to the lint (never_type_fallback_flowing_into_unsafe) --- compiler/rustc_hir_typeck/messages.ftl | 9 +- compiler/rustc_hir_typeck/src/errors.rs | 6 +- compiler/rustc_hir_typeck/src/fallback.rs | 171 ++++++++++++++---- ...never-type-fallback-flowing-into-unsafe.rs | 110 ++++++++++- ...r-type-fallback-flowing-into-unsafe.stderr | 70 ++++++- 5 files changed, 319 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 0caebf44a193..ed288251021d 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -100,7 +100,14 @@ hir_typeck_lossy_provenance_ptr2int = hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}` hir_typeck_never_type_fallback_flowing_into_unsafe = - never type fallback affects this call to an `unsafe` function + never type fallback affects this {$reason -> + [call] call to an `unsafe` function + [union_field] union access + [deref] raw pointer dereference + [path] `unsafe` function + [method] call to an `unsafe` method + *[other] THIS SHOULD NOT BE REACHABLE + } .help = specify the type explicitly hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method -> diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index fcad88f829e2..2bb46c8d288c 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -1,7 +1,7 @@ //! Errors emitted by `rustc_hir_typeck`. use std::borrow::Cow; -use crate::fluent_generated as fluent; +use crate::{fallback::UnsafeUseReason, fluent_generated as fluent}; use rustc_errors::{ codes::*, Applicability, Diag, DiagArgValue, EmissionGuarantee, IntoDiagArg, MultiSpan, SubdiagMessageOp, Subdiagnostic, @@ -167,7 +167,9 @@ pub struct MissingParenthesesInRange { #[derive(LintDiagnostic)] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe)] #[help] -pub struct NeverTypeFallbackFlowingIntoUnsafe {} +pub struct NeverTypeFallbackFlowingIntoUnsafe { + pub reason: UnsafeUseReason, +} #[derive(Subdiagnostic)] #[multipart_suggestion( diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 52ece8887b97..7a8919154547 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -1,10 +1,11 @@ -use std::cell::OnceCell; +use std::{borrow::Cow, cell::OnceCell}; use crate::{errors, FnCtxt, TypeckRootCtxt}; use rustc_data_structures::{ graph::{self, iterate::DepthFirstSearch, vec_graph::VecGraph}, unord::{UnordBag, UnordMap, UnordSet}, }; +use rustc_errors::{DiagArgValue, IntoDiagArg}; use rustc_hir as hir; use rustc_hir::intravisit::Visitor; use rustc_hir::HirId; @@ -374,12 +375,12 @@ impl<'tcx> FnCtxt<'_, 'tcx> { .filter_map(|x| unsafe_infer_vars.get(&x).copied()) .collect::>(); - for (hir_id, span) in affected_unsafe_infer_vars { + for (hir_id, span, reason) in affected_unsafe_infer_vars { self.tcx.emit_node_span_lint( lint::builtin::NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE, hir_id, span, - errors::NeverTypeFallbackFlowingIntoUnsafe {}, + errors::NeverTypeFallbackFlowingIntoUnsafe { reason }, ); } @@ -493,77 +494,169 @@ impl<'tcx> FnCtxt<'_, 'tcx> { } } -/// Finds all type variables which are passed to an `unsafe` function. +#[derive(Debug, Copy, Clone)] +pub(crate) enum UnsafeUseReason { + Call, + Method, + Path, + UnionField, + Deref, +} + +impl IntoDiagArg for UnsafeUseReason { + fn into_diag_arg(self) -> DiagArgValue { + let s = match self { + UnsafeUseReason::Call => "call", + UnsafeUseReason::Method => "method", + UnsafeUseReason::Path => "path", + UnsafeUseReason::UnionField => "union_field", + UnsafeUseReason::Deref => "deref", + }; + DiagArgValue::Str(Cow::Borrowed(s)) + } +} + +/// Finds all type variables which are passed to an `unsafe` operation. /// /// For example, for this function `f`: /// ```ignore (demonstrative) /// fn f() { /// unsafe { /// let x /* ?X */ = core::mem::zeroed(); -/// // ^^^^^^^^^^^^^^^^^^^ -- hir_id, span +/// // ^^^^^^^^^^^^^^^^^^^ -- hir_id, span, reason /// /// let y = core::mem::zeroed::>(); -/// // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- hir_id, span +/// // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- hir_id, span, reason /// } /// } /// ``` /// -/// Will return `{ id(?X) -> (hir_id, span) }` +/// `compute_unsafe_infer_vars` will return `{ id(?X) -> (hir_id, span, Call) }` fn compute_unsafe_infer_vars<'a, 'tcx>( root_ctxt: &'a TypeckRootCtxt<'tcx>, body_id: LocalDefId, -) -> UnordMap { - let tcx = root_ctxt.infcx.tcx; - let body_id = tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner"); - let body = tcx.hir().body(body_id); +) -> UnordMap { + let body_id = + root_ctxt.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner"); + let body = root_ctxt.tcx.hir().body(body_id); let mut res = UnordMap::default(); struct UnsafeInferVarsVisitor<'a, 'tcx, 'r> { root_ctxt: &'a TypeckRootCtxt<'tcx>, - res: &'r mut UnordMap, + res: &'r mut UnordMap, } impl Visitor<'_> for UnsafeInferVarsVisitor<'_, '_, '_> { fn visit_expr(&mut self, ex: &'_ hir::Expr<'_>) { - // FIXME: method calls - if let hir::ExprKind::Call(func, ..) = ex.kind { - let typeck_results = self.root_ctxt.typeck_results.borrow(); + let typeck_results = self.root_ctxt.typeck_results.borrow(); - let func_ty = typeck_results.expr_ty(func); + match ex.kind { + hir::ExprKind::MethodCall(..) => { + if let Some(def_id) = typeck_results.type_dependent_def_id(ex.hir_id) + && let method_ty = self.root_ctxt.tcx.type_of(def_id).instantiate_identity() + && let sig = method_ty.fn_sig(self.root_ctxt.tcx) + && let hir::Unsafety::Unsafe = sig.unsafety() + { + let mut collector = InferVarCollector { + value: (ex.hir_id, ex.span, UnsafeUseReason::Method), + res: self.res, + }; - // `is_fn` is required to ignore closures (which can't be unsafe) - if func_ty.is_fn() - && let sig = func_ty.fn_sig(self.root_ctxt.infcx.tcx) - && let hir::Unsafety::Unsafe = sig.unsafety() - { - let mut collector = - InferVarCollector { hir_id: ex.hir_id, call_span: ex.span, res: self.res }; - - // Collect generic arguments of the function which are inference variables - typeck_results - .node_args(ex.hir_id) - .types() - .for_each(|t| t.visit_with(&mut collector)); - - // Also check the return type, for cases like `(unsafe_fn::<_> as unsafe fn() -> _)()` - sig.output().visit_with(&mut collector); + // Collect generic arguments (incl. `Self`) of the method + typeck_results + .node_args(ex.hir_id) + .types() + .for_each(|t| t.visit_with(&mut collector)); + } } - } + + hir::ExprKind::Call(func, ..) => { + let func_ty = typeck_results.expr_ty(func); + + if func_ty.is_fn() + && let sig = func_ty.fn_sig(self.root_ctxt.tcx) + && let hir::Unsafety::Unsafe = sig.unsafety() + { + let mut collector = InferVarCollector { + value: (ex.hir_id, ex.span, UnsafeUseReason::Call), + res: self.res, + }; + + // Try collecting generic arguments of the function. + // Note that we do this below for any paths (that don't have to be called), + // but there we do it with a different span/reason. + // This takes priority. + typeck_results + .node_args(func.hir_id) + .types() + .for_each(|t| t.visit_with(&mut collector)); + + // Also check the return type, for cases like `returns_unsafe_fn_ptr()()` + sig.output().visit_with(&mut collector); + } + } + + // Check paths which refer to functions. + // We do this, instead of only checking `Call` to make sure the lint can't be + // avoided by storing unsafe function in a variable. + hir::ExprKind::Path(_) => { + let ty = typeck_results.expr_ty(ex); + + // If this path refers to an unsafe function, collect inference variables which may affect it. + // `is_fn` excludes closures, but those can't be unsafe. + if ty.is_fn() + && let sig = ty.fn_sig(self.root_ctxt.tcx) + && let hir::Unsafety::Unsafe = sig.unsafety() + { + let mut collector = InferVarCollector { + value: (ex.hir_id, ex.span, UnsafeUseReason::Path), + res: self.res, + }; + + // Collect generic arguments of the function + typeck_results + .node_args(ex.hir_id) + .types() + .for_each(|t| t.visit_with(&mut collector)); + } + } + + hir::ExprKind::Unary(hir::UnOp::Deref, pointer) => { + if let ty::RawPtr(pointee, _) = typeck_results.expr_ty(pointer).kind() { + pointee.visit_with(&mut InferVarCollector { + value: (ex.hir_id, ex.span, UnsafeUseReason::Deref), + res: self.res, + }); + } + } + + hir::ExprKind::Field(base, _) => { + let base_ty = typeck_results.expr_ty(base); + + if base_ty.is_union() { + typeck_results.expr_ty(ex).visit_with(&mut InferVarCollector { + value: (ex.hir_id, ex.span, UnsafeUseReason::UnionField), + res: self.res, + }); + } + } + + _ => (), + }; hir::intravisit::walk_expr(self, ex); } } - struct InferVarCollector<'r> { - hir_id: HirId, - call_span: Span, - res: &'r mut UnordMap, + struct InferVarCollector<'r, V> { + value: V, + res: &'r mut UnordMap, } - impl<'tcx> ty::TypeVisitor> for InferVarCollector<'_> { + impl<'tcx, V: Copy> ty::TypeVisitor> for InferVarCollector<'_, V> { fn visit_ty(&mut self, t: Ty<'tcx>) { if let Some(vid) = t.ty_vid() { - self.res.insert(vid, (self.hir_id, self.call_span)); + _ = self.res.try_insert(vid, self.value); } else { t.super_visit_with(self) } diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs index f13e20cc0f2f..0ae498c134f0 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs @@ -1,7 +1,9 @@ //@ check-pass -use std::mem; +use std::{marker, mem, ptr}; -fn main() { +fn main() {} + +fn _zero() { if false { unsafe { mem::zeroed() } //~^ warn: never type fallback affects this call to an `unsafe` function @@ -13,6 +15,110 @@ fn main() { if true { unsafe { mem::zeroed() } } else { return } } +fn _trans() { + if false { + unsafe { + struct Zst; + core::mem::transmute(Zst) + //~^ warn: never type fallback affects this call to an `unsafe` function + } + } else { + return; + }; +} + +fn _union() { + if false { + union Union { + a: (), + b: T, + } + + unsafe { Union { a: () }.b } + //~^ warn: never type fallback affects this union access + } else { + return; + }; +} + +fn _deref() { + if false { + unsafe { *ptr::from_ref(&()).cast() } + //~^ warn: never type fallback affects this raw pointer dereference + } else { + return; + }; +} + +fn _only_generics() { + if false { + unsafe fn internally_create(_: Option) { + let _ = mem::zeroed::(); + } + + // We need the option (and unwrap later) to call a function in a way, + // which makes it affected by the fallback, but without having it return anything + let x = None; + + unsafe { internally_create(x) } + //~^ warn: never type fallback affects this call to an `unsafe` function + + x.unwrap() + } else { + return; + }; +} + +fn _stored_function() { + if false { + let zeroed = mem::zeroed; + //~^ warn: never type fallback affects this `unsafe` function + + unsafe { zeroed() } + //~^ warn: never type fallback affects this call to an `unsafe` function + } else { + return; + }; +} + +fn _only_generics_stored_function() { + if false { + unsafe fn internally_create(_: Option) { + let _ = mem::zeroed::(); + } + + let x = None; + let f = internally_create; + //~^ warn: never type fallback affects this `unsafe` function + + unsafe { f(x) } + + x.unwrap() + } else { + return; + }; +} + +fn _method() { + struct S(marker::PhantomData); + + impl S { + #[allow(unused)] // FIXME: the unused lint is probably incorrect here + unsafe fn create_out_of_thin_air(&self) -> T { + todo!() + } + } + + if false { + unsafe { + S(marker::PhantomData).create_out_of_thin_air() + //~^ warn: never type fallback affects this call to an `unsafe` method + } + } else { + return; + }; +} + // Minimization of the famous `objc` crate issue fn _objc() { pub unsafe fn send_message() -> Result { diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr index 1610804c29b9..84c9385fd139 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr @@ -1,5 +1,5 @@ warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:6:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:8:18 | LL | unsafe { mem::zeroed() } | ^^^^^^^^^^^^^ @@ -8,7 +8,71 @@ LL | unsafe { mem::zeroed() } = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:24:19 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:22:13 + | +LL | core::mem::transmute(Zst) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: specify the type explicitly + +warning: never type fallback affects this union access + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:37:18 + | +LL | unsafe { Union { a: () }.b } + | ^^^^^^^^^^^^^^^^^ + | + = help: specify the type explicitly + +warning: never type fallback affects this raw pointer dereference + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:46:18 + | +LL | unsafe { *ptr::from_ref(&()).cast() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: specify the type explicitly + +warning: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:63:18 + | +LL | unsafe { internally_create(x) } + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: specify the type explicitly + +warning: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:77:18 + | +LL | unsafe { zeroed() } + | ^^^^^^^^ + | + = help: specify the type explicitly + +warning: never type fallback affects this `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:74:22 + | +LL | let zeroed = mem::zeroed; + | ^^^^^^^^^^^ + | + = help: specify the type explicitly + +warning: never type fallback affects this `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:91:17 + | +LL | let f = internally_create; + | ^^^^^^^^^^^^^^^^^ + | + = help: specify the type explicitly + +warning: never type fallback affects this call to an `unsafe` method + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:114:13 + | +LL | S(marker::PhantomData).create_out_of_thin_air() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: specify the type explicitly + +warning: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:130:19 | LL | match send_message::<_ /* ?0 */>() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,5 +83,5 @@ LL | msg_send!(); = help: specify the type explicitly = note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) -warning: 2 warnings emitted +warning: 10 warnings emitted From b5626172d13bed3f82ead73493e548d6df9bf63a Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 2 May 2024 03:29:18 +0200 Subject: [PATCH 231/279] Split `hir_typeck_never_type_fallback_flowing_into_unsafe` into 5 slugs --- compiler/rustc_hir_typeck/messages.ftl | 18 ++++++------ compiler/rustc_hir_typeck/src/errors.rs | 22 +++++++++++---- compiler/rustc_hir_typeck/src/fallback.rs | 34 ++++++++++++----------- 3 files changed, 44 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index ed288251021d..0560d0d902a3 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -99,15 +99,15 @@ hir_typeck_lossy_provenance_ptr2int = hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}` -hir_typeck_never_type_fallback_flowing_into_unsafe = - never type fallback affects this {$reason -> - [call] call to an `unsafe` function - [union_field] union access - [deref] raw pointer dereference - [path] `unsafe` function - [method] call to an `unsafe` method - *[other] THIS SHOULD NOT BE REACHABLE - } +hir_typeck_never_type_fallback_flowing_into_unsafe_call = never type fallback affects this call to an `unsafe` function + .help = specify the type explicitly +hir_typeck_never_type_fallback_flowing_into_unsafe_deref = never type fallback affects this raw pointer dereference + .help = specify the type explicitly +hir_typeck_never_type_fallback_flowing_into_unsafe_method = never type fallback affects this call to an `unsafe` method + .help = specify the type explicitly +hir_typeck_never_type_fallback_flowing_into_unsafe_path = never type fallback affects this `unsafe` function + .help = specify the type explicitly +hir_typeck_never_type_fallback_flowing_into_unsafe_union_field = never type fallback affects this union access .help = specify the type explicitly hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method -> diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 2bb46c8d288c..ba8f246fd8d2 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -1,7 +1,7 @@ //! Errors emitted by `rustc_hir_typeck`. use std::borrow::Cow; -use crate::{fallback::UnsafeUseReason, fluent_generated as fluent}; +use crate::fluent_generated as fluent; use rustc_errors::{ codes::*, Applicability, Diag, DiagArgValue, EmissionGuarantee, IntoDiagArg, MultiSpan, SubdiagMessageOp, Subdiagnostic, @@ -165,10 +165,22 @@ pub struct MissingParenthesesInRange { } #[derive(LintDiagnostic)] -#[diag(hir_typeck_never_type_fallback_flowing_into_unsafe)] -#[help] -pub struct NeverTypeFallbackFlowingIntoUnsafe { - pub reason: UnsafeUseReason, +pub enum NeverTypeFallbackFlowingIntoUnsafe { + #[help] + #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_call)] + Call, + #[help] + #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_method)] + Method, + #[help] + #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_path)] + Path, + #[help] + #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_union_field)] + UnionField, + #[help] + #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_deref)] + Deref, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 7a8919154547..f240a53a6797 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -1,11 +1,10 @@ -use std::{borrow::Cow, cell::OnceCell}; +use std::cell::OnceCell; use crate::{errors, FnCtxt, TypeckRootCtxt}; use rustc_data_structures::{ graph::{self, iterate::DepthFirstSearch, vec_graph::VecGraph}, unord::{UnordBag, UnordMap, UnordSet}, }; -use rustc_errors::{DiagArgValue, IntoDiagArg}; use rustc_hir as hir; use rustc_hir::intravisit::Visitor; use rustc_hir::HirId; @@ -380,7 +379,23 @@ impl<'tcx> FnCtxt<'_, 'tcx> { lint::builtin::NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE, hir_id, span, - errors::NeverTypeFallbackFlowingIntoUnsafe { reason }, + match reason { + UnsafeUseReason::Call => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Call + } + UnsafeUseReason::Method => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Method + } + UnsafeUseReason::Path => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Path + } + UnsafeUseReason::UnionField => { + errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField + } + UnsafeUseReason::Deref => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Deref + } + }, ); } @@ -503,19 +518,6 @@ pub(crate) enum UnsafeUseReason { Deref, } -impl IntoDiagArg for UnsafeUseReason { - fn into_diag_arg(self) -> DiagArgValue { - let s = match self { - UnsafeUseReason::Call => "call", - UnsafeUseReason::Method => "method", - UnsafeUseReason::Path => "path", - UnsafeUseReason::UnionField => "union_field", - UnsafeUseReason::Deref => "deref", - }; - DiagArgValue::Str(Cow::Borrowed(s)) - } -} - /// Finds all type variables which are passed to an `unsafe` operation. /// /// For example, for this function `f`: From 3a40e838bfc22c6415e32fcd94fd48e83e1844b1 Mon Sep 17 00:00:00 2001 From: Waffle Maybe Date: Thu, 2 May 2024 04:13:57 +0200 Subject: [PATCH 232/279] Apply suggestions from code review Co-authored-by: Kevin Reid Co-authored-by: Herman Skogseth Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com> --- library/core/src/primitive_docs.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 1839c56f16dd..d9c81239fc4b 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -270,8 +270,8 @@ mod prim_bool {} /// /// # Never type fallback /// -/// When the compiler sees a value of type `!` it implicitly inserts a coercion (if possible) -/// to allow type checker to infer any type: +/// When the compiler sees a value of type `!` in a [coercion site](https://doc.rust-lang.org/reference/type-coercions.html#coercion-sites), it implicitly inserts a coercion +/// to allow the type checker to infer any type: /// /// ```rust,ignore (illustrative-and-has-placeholders) /// // this @@ -286,8 +286,7 @@ mod prim_bool {} // FIXME: use `core::convert::absurd` here instead, once it's merged /// ``` /// -/// While it's convenient to be able to use non-diverging code in one of the branches (like -/// `if a { b } else { return }`) this could lead to compilation errors: +/// This can lead to compilation errors if the type cannot be inferred: /// /// ```compile_fail /// // this @@ -298,7 +297,7 @@ mod prim_bool {} /// ``` /// /// To prevent such errors, the compiler remembers where it inserted `absurd` calls, and -/// if it can't infer their type, it sets the type to the fallback type: +/// if it can't infer the type, it uses the fallback type instead: /// ```rust, ignore /// type Fallback = /* An arbitrarily selected type! */; /// { absurd::(panic!()) } @@ -306,9 +305,9 @@ mod prim_bool {} /// /// This is what is known as "never type fallback". /// -/// Historically fallback was [`()`], causing confusing behavior where `!` spontaneously coerced -/// to `()`, even though `()` was never mentioned (because of the fallback). There are plans to -/// change it in 2024 edition (and possibly in all editions on a later date), see +/// Historically, the fallback type was [`()`], causing confusing behavior where `!` spontaneously coerced +/// to `()`, even when it would not infer `()` without the fallback. There are plans to +/// change it in the [2024 edition](https://doc.rust-lang.org/nightly/edition-guide/rust-2024/index.html) (and possibly in all editions on a later date); see /// [Tracking Issue for making `!` fall back to `!`][fallback-ti]. /// /// [`()`]: prim@unit From a64f94161130944f8fda1f6dcc00f37860f43ecf Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 29 Apr 2024 09:27:34 -0400 Subject: [PATCH 233/279] Step bootstrap cfgs --- compiler/rustc_ast/src/lib.rs | 1 - compiler/rustc_borrowck/src/lib.rs | 1 - .../rustc_codegen_gcc/example/mini_core.rs | 1 - compiler/rustc_codegen_gcc/src/lib.rs | 1 - compiler/rustc_codegen_ssa/src/lib.rs | 1 - compiler/rustc_expand/src/lib.rs | 1 - compiler/rustc_infer/src/lib.rs | 1 - compiler/rustc_metadata/src/rmeta/decoder.rs | 2 +- compiler/rustc_middle/src/lib.rs | 2 - compiler/rustc_middle/src/ty/closure.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_mir_build/src/lib.rs | 1 - compiler/rustc_mir_transform/src/lib.rs | 1 - compiler/rustc_serialize/src/lib.rs | 2 - compiler/rustc_trait_selection/src/lib.rs | 1 - library/alloc/src/lib.rs | 4 +- library/alloc/tests/lib.rs | 1 - library/core/src/cmp.rs | 38 ++------ library/core/src/default.rs | 2 - library/core/src/future/mod.rs | 2 - library/core/src/intrinsics.rs | 91 +------------------ library/core/src/intrinsics/simd.rs | 13 --- .../core/src/iter/sources/from_coroutine.rs | 2 +- library/core/src/iter/traits/marker.rs | 2 +- library/core/src/lib.rs | 5 +- library/core/src/macros/mod.rs | 1 - library/core/src/num/int_macros.rs | 24 +---- library/core/src/num/nonzero.rs | 10 +- library/core/src/num/uint_macros.rs | 39 +------- library/core/src/ops/coroutine.rs | 2 +- library/core/src/ops/deref.rs | 2 +- library/core/src/ops/drop.rs | 1 - library/core/src/ops/mod.rs | 1 - library/core/src/panicking.rs | 1 - library/core/src/pin.rs | 2 +- library/core/src/prelude/common.rs | 1 - library/core/src/ptr/metadata.rs | 25 +---- library/core/src/ptr/mod.rs | 9 -- library/core/src/sync/atomic.rs | 3 - library/core/tests/intrinsics.rs | 1 - library/core/tests/lib.rs | 3 +- library/std/src/lib.rs | 3 +- library/std/src/prelude/common.rs | 1 - src/bootstrap/src/core/builder.rs | 11 +-- 44 files changed, 38 insertions(+), 282 deletions(-) diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 9193867a10c9..63cde3c6809c 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -11,7 +11,6 @@ #![doc(rust_logo)] #![allow(internal_features)] #![feature(rustdoc_internals)] -#![cfg_attr(bootstrap, feature(associated_type_bounds))] #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(if_let_guard)] diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 2da8ff240c6e..47c83e0bb2bb 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -4,7 +4,6 @@ #![feature(rustdoc_internals)] #![doc(rust_logo)] #![feature(assert_matches)] -#![cfg_attr(bootstrap, feature(associated_type_bounds))] #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(let_chains)] diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs index 8ffa66a48946..a48c0a4450c2 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core.rs @@ -420,7 +420,6 @@ pub fn panic(_msg: &'static str) -> ! { macro_rules! panic_const { ($($lang:ident = $message:expr,)+) => { - #[cfg(not(bootstrap))] pub mod panic_const { use super::*; diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 345c22394f21..3f2fadce9e4d 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -23,7 +23,6 @@ trusted_len, hash_raw_entry )] -#![cfg_attr(bootstrap, feature(associated_type_bounds))] #![allow(broken_intra_doc_links)] #![recursion_limit = "256"] #![warn(rust_2018_idioms)] diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 46e1410a509a..4eb24d71009a 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -4,7 +4,6 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![cfg_attr(bootstrap, feature(associated_type_bounds))] #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(let_chains)] diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index c095584f3c7c..3c9d2e870683 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -1,7 +1,6 @@ #![doc(rust_logo)] #![feature(rustdoc_internals)] #![feature(array_windows)] -#![cfg_attr(bootstrap, feature(associated_type_bounds))] #![feature(associated_type_defaults)] #![feature(if_let_guard)] #![feature(let_chains)] diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 9370e84a19a6..0299af61d45c 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -18,7 +18,6 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![cfg_attr(bootstrap, feature(associated_type_bounds))] #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(extend_one)] diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index fd42c9c1faaf..2a33088513b7 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1261,7 +1261,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { sess: &'a Session, ) -> impl Iterator + 'a { iter::from_coroutine( - #[cfg_attr(not(bootstrap), coroutine)] + #[coroutine] move || { if let Some(data) = &self.root.proc_macro_data { // If we are loading as a proc macro, we want to return diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 146dcf183b1d..04fd4c8d0f7b 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -37,7 +37,6 @@ #![feature(coroutines)] #![feature(stmt_expr_attributes)] #![feature(if_let_guard)] -#![cfg_attr(bootstrap, feature(inline_const))] #![feature(iter_from_coroutine)] #![feature(negative_impls)] #![feature(never_type)] @@ -48,7 +47,6 @@ #![feature(trusted_len)] #![feature(type_alias_impl_trait)] #![feature(strict_provenance)] -#![cfg_attr(bootstrap, feature(associated_type_bounds))] #![feature(rustc_attrs)] #![feature(control_flow_enum)] #![feature(trait_upcasting)] diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 8096acd9b0fe..bade0d564156 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -424,7 +424,7 @@ pub fn analyze_coroutine_closure_captures<'a, 'tcx: 'a, T>( mut for_each: impl FnMut((usize, &'a CapturedPlace<'tcx>), (usize, &'a CapturedPlace<'tcx>)) -> T, ) -> impl Iterator + Captures<'a> + Captures<'tcx> { std::iter::from_coroutine( - #[cfg_attr(not(bootstrap), coroutine)] + #[coroutine] move || { let mut child_captures = child_captures.into_iter().enumerate().peekable(); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 434c95370744..d2eacdf762f1 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1285,7 +1285,7 @@ impl<'tcx> TyCtxt<'tcx> { let definitions = &self.untracked.definitions; std::iter::from_coroutine( - #[cfg_attr(not(bootstrap), coroutine)] + #[coroutine] || { let mut i = 0; diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 442f5fa7d172..e79e3b887fb4 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -5,7 +5,6 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] #![feature(assert_matches)] -#![cfg_attr(bootstrap, feature(associated_type_bounds))] #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(let_chains)] diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index e42755ca7bf2..e69c5da757ed 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -4,7 +4,6 @@ #![feature(cow_is_borrowed)] #![feature(decl_macro)] #![feature(impl_trait_in_assoc_type)] -#![cfg_attr(bootstrap, feature(inline_const))] #![feature(is_sorted)] #![feature(let_chains)] #![feature(map_try_insert)] diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 19f4e6994acf..532b749f9136 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -8,10 +8,8 @@ #![doc(rust_logo)] #![allow(internal_features)] #![feature(rustdoc_internals)] -#![cfg_attr(bootstrap, feature(associated_type_bounds))] #![feature(const_option)] #![feature(core_intrinsics)] -#![cfg_attr(bootstrap, feature(inline_const))] #![feature(min_specialization)] #![feature(never_type)] #![feature(ptr_sub_ptr)] diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 5789ec2b1f18..f1f03b810a96 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -17,7 +17,6 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] #![feature(assert_matches)] -#![cfg_attr(bootstrap, feature(associated_type_bounds))] #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(control_flow_enum)] diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 4e8792f6fb99..b93936869b3f 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -165,9 +165,6 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(associated_type_bounds))] -#![cfg_attr(bootstrap, feature(inline_const))] -#![cfg_attr(not(bootstrap), rustc_preserve_ub_checks)] #![cfg_attr(not(test), feature(coroutine_trait))] #![cfg_attr(test, feature(panic_update_hook))] #![cfg_attr(test, feature(test))] @@ -198,6 +195,7 @@ #![feature(unboxed_closures)] #![feature(unsized_fn_params)] #![feature(with_negative_coherence)] +#![rustc_preserve_ub_checks] // tidy-alphabetical-end // // Rustdoc features: diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index b5175a8487f4..0eae4ca4b8ba 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -1,4 +1,3 @@ -#![cfg_attr(bootstrap, feature(associated_type_bounds))] #![feature(allocator_api)] #![feature(alloc_layout_extra)] #![feature(iter_array_chunks)] diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 2fd9e17c994f..fc6022ab7535 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -379,7 +379,7 @@ pub struct AssertParamIsEq { // This is a lang item only so that `BinOp::Cmp` in MIR can return it. // It has no special behaviour, but does require that the three variants // `Less`/`Equal`/`Greater` remain `-1_i8`/`0_i8`/`+1_i8` respectively. -#[cfg_attr(not(bootstrap), lang = "Ordering")] +#[lang = "Ordering"] #[repr(i8)] pub enum Ordering { /// An ordering where a compared value is less than another. @@ -852,7 +852,7 @@ pub trait Ord: Eq + PartialOrd { #[stable(feature = "ord_max_min", since = "1.21.0")] #[inline] #[must_use] - #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_ord_max")] + #[rustc_diagnostic_item = "cmp_ord_max"] fn max(self, other: Self) -> Self where Self: Sized, @@ -873,7 +873,7 @@ pub trait Ord: Eq + PartialOrd { #[stable(feature = "ord_max_min", since = "1.21.0")] #[inline] #[must_use] - #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_ord_min")] + #[rustc_diagnostic_item = "cmp_ord_min"] fn min(self, other: Self) -> Self where Self: Sized, @@ -1160,7 +1160,7 @@ pub trait PartialOrd: PartialEq { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialord_cmp")] + #[rustc_diagnostic_item = "cmp_partialord_cmp"] fn partial_cmp(&self, other: &Rhs) -> Option; /// This method tests less than (for `self` and `other`) and is used by the `<` operator. @@ -1175,7 +1175,7 @@ pub trait PartialOrd: PartialEq { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialord_lt")] + #[rustc_diagnostic_item = "cmp_partialord_lt"] fn lt(&self, other: &Rhs) -> bool { matches!(self.partial_cmp(other), Some(Less)) } @@ -1193,7 +1193,7 @@ pub trait PartialOrd: PartialEq { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialord_le")] + #[rustc_diagnostic_item = "cmp_partialord_le"] fn le(&self, other: &Rhs) -> bool { matches!(self.partial_cmp(other), Some(Less | Equal)) } @@ -1210,7 +1210,7 @@ pub trait PartialOrd: PartialEq { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialord_gt")] + #[rustc_diagnostic_item = "cmp_partialord_gt"] fn gt(&self, other: &Rhs) -> bool { matches!(self.partial_cmp(other), Some(Greater)) } @@ -1228,7 +1228,7 @@ pub trait PartialOrd: PartialEq { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialord_ge")] + #[rustc_diagnostic_item = "cmp_partialord_ge"] fn ge(&self, other: &Rhs) -> bool { matches!(self.partial_cmp(other), Some(Greater | Equal)) } @@ -1558,14 +1558,7 @@ mod impls { impl PartialOrd for $t { #[inline] fn partial_cmp(&self, other: &$t) -> Option { - #[cfg(bootstrap)] - { - Some(self.cmp(other)) - } - #[cfg(not(bootstrap))] - { - Some(crate::intrinsics::three_way_compare(*self, *other)) - } + Some(crate::intrinsics::three_way_compare(*self, *other)) } #[inline(always)] fn lt(&self, other: &$t) -> bool { (*self) < (*other) } @@ -1581,18 +1574,7 @@ mod impls { impl Ord for $t { #[inline] fn cmp(&self, other: &$t) -> Ordering { - #[cfg(bootstrap)] - { - // The order here is important to generate more optimal assembly. - // See for more info. - if *self < *other { Less } - else if *self == *other { Equal } - else { Greater } - } - #[cfg(not(bootstrap))] - { - crate::intrinsics::three_way_compare(*self, *other) - } + crate::intrinsics::three_way_compare(*self, *other) } } )*) diff --git a/library/core/src/default.rs b/library/core/src/default.rs index e717a8d022fa..4524b352ec81 100644 --- a/library/core/src/default.rs +++ b/library/core/src/default.rs @@ -178,9 +178,7 @@ default_impl! { i32, 0, "Returns the default value of `0`" } default_impl! { i64, 0, "Returns the default value of `0`" } default_impl! { i128, 0, "Returns the default value of `0`" } -#[cfg(not(bootstrap))] default_impl! { f16, 0.0f16, "Returns the default value of `0.0`" } default_impl! { f32, 0.0f32, "Returns the default value of `0.0`" } default_impl! { f64, 0.0f64, "Returns the default value of `0.0`" } -#[cfg(not(bootstrap))] default_impl! { f128, 0.0f128, "Returns the default value of `0.0`" } diff --git a/library/core/src/future/mod.rs b/library/core/src/future/mod.rs index c3bd18e30aa4..873cccc7e96f 100644 --- a/library/core/src/future/mod.rs +++ b/library/core/src/future/mod.rs @@ -12,7 +12,6 @@ use crate::ptr::NonNull; use crate::task::Context; -#[cfg(not(bootstrap))] mod async_drop; mod future; mod into_future; @@ -38,7 +37,6 @@ pub use ready::{ready, Ready}; #[stable(feature = "future_poll_fn", since = "1.64.0")] pub use poll_fn::{poll_fn, PollFn}; -#[cfg(not(bootstrap))] #[unstable(feature = "async_drop", issue = "none")] pub use async_drop::{async_drop, async_drop_in_place, AsyncDrop, AsyncDropInPlace}; diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index dc41fb5a7784..3318a8ffa554 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1987,18 +1987,11 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `count_ones` method. For example, /// [`u32::count_ones`] - #[cfg(not(bootstrap))] #[rustc_const_stable(feature = "const_ctpop", since = "1.40.0")] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn ctpop(x: T) -> u32; - #[cfg(bootstrap)] - #[rustc_const_stable(feature = "const_ctpop", since = "1.40.0")] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn ctpop(x: T) -> T; - /// Returns the number of leading unset bits (zeroes) in an integer type `T`. /// /// Note that, unlike most intrinsics, this is safe to call; @@ -2035,18 +2028,11 @@ extern "rust-intrinsic" { /// let num_leading = ctlz(x); /// assert_eq!(num_leading, 16); /// ``` - #[cfg(not(bootstrap))] #[rustc_const_stable(feature = "const_ctlz", since = "1.40.0")] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn ctlz(x: T) -> u32; - #[cfg(bootstrap)] - #[rustc_const_stable(feature = "const_ctlz", since = "1.40.0")] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn ctlz(x: T) -> T; - /// Like `ctlz`, but extra-unsafe as it returns `undef` when /// given an `x` with value `0`. /// @@ -2064,16 +2050,10 @@ extern "rust-intrinsic" { /// let num_leading = unsafe { ctlz_nonzero(x) }; /// assert_eq!(num_leading, 3); /// ``` - #[cfg(not(bootstrap))] #[rustc_const_stable(feature = "constctlz", since = "1.50.0")] #[rustc_nounwind] pub fn ctlz_nonzero(x: T) -> u32; - #[cfg(bootstrap)] - #[rustc_const_stable(feature = "constctlz", since = "1.50.0")] - #[rustc_nounwind] - pub fn ctlz_nonzero(x: T) -> T; - /// Returns the number of trailing unset bits (zeroes) in an integer type `T`. /// /// Note that, unlike most intrinsics, this is safe to call; @@ -2110,18 +2090,11 @@ extern "rust-intrinsic" { /// let num_trailing = cttz(x); /// assert_eq!(num_trailing, 16); /// ``` - #[cfg(not(bootstrap))] #[rustc_const_stable(feature = "const_cttz", since = "1.40.0")] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn cttz(x: T) -> u32; - #[cfg(bootstrap)] - #[rustc_const_stable(feature = "const_cttz", since = "1.40.0")] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn cttz(x: T) -> T; - /// Like `cttz`, but extra-unsafe as it returns `undef` when /// given an `x` with value `0`. /// @@ -2139,16 +2112,10 @@ extern "rust-intrinsic" { /// let num_trailing = unsafe { cttz_nonzero(x) }; /// assert_eq!(num_trailing, 3); /// ``` - #[cfg(not(bootstrap))] #[rustc_const_stable(feature = "const_cttz_nonzero", since = "1.53.0")] #[rustc_nounwind] pub fn cttz_nonzero(x: T) -> u32; - #[cfg(bootstrap)] - #[rustc_const_stable(feature = "const_cttz_nonzero", since = "1.53.0")] - #[rustc_nounwind] - pub fn cttz_nonzero(x: T) -> T; - /// Reverses the bytes in an integer type `T`. /// /// Note that, unlike most intrinsics, this is safe to call; @@ -2186,7 +2153,6 @@ extern "rust-intrinsic" { /// large and difficult to optimize. /// /// The stabilized version of this intrinsic is [`Ord::cmp`]. - #[cfg(not(bootstrap))] #[rustc_const_unstable(feature = "const_three_way_compare", issue = "none")] #[rustc_safe_intrinsic] pub fn three_way_compare(lhs: T, rhs: T) -> crate::cmp::Ordering; @@ -2269,7 +2235,6 @@ extern "rust-intrinsic" { /// Safe wrappers for this intrinsic are available on the integer /// primitives via the `checked_shl` method. For example, /// [`u32::checked_shl`] - #[cfg(not(bootstrap))] #[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")] #[rustc_nounwind] pub fn unchecked_shl(x: T, y: U) -> T; @@ -2279,7 +2244,6 @@ extern "rust-intrinsic" { /// Safe wrappers for this intrinsic are available on the integer /// primitives via the `checked_shr` method. For example, /// [`u32::checked_shr`] - #[cfg(not(bootstrap))] #[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")] #[rustc_nounwind] pub fn unchecked_shr(x: T, y: U) -> T; @@ -2321,18 +2285,11 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `rotate_left` method. For example, /// [`u32::rotate_left`] - #[cfg(not(bootstrap))] #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn rotate_left(x: T, shift: u32) -> T; - #[cfg(bootstrap)] - #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn rotate_left(x: T, y: T) -> T; - /// Performs rotate right. /// /// Note that, unlike most intrinsics, this is safe to call; @@ -2343,18 +2300,11 @@ extern "rust-intrinsic" { /// The stabilized versions of this intrinsic are available on the integer /// primitives via the `rotate_right` method. For example, /// [`u32::rotate_right`] - #[cfg(not(bootstrap))] #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn rotate_right(x: T, shift: u32) -> T; - #[cfg(bootstrap)] - #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn rotate_right(x: T, y: T) -> T; - /// Returns (a + b) mod 2N, where N is the width of T in bits. /// /// Note that, unlike most intrinsics, this is safe to call; @@ -2507,12 +2457,6 @@ extern "rust-intrinsic" { #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] #[rustc_nounwind] pub fn ptr_offset_from_unsigned(ptr: *const T, base: *const T) -> usize; - - #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - #[cfg(bootstrap)] - pub fn ptr_guaranteed_cmp(ptr: *const T, other: *const T) -> u8; } /// See documentation of `<*const T>::guaranteed_eq` for details. @@ -2522,7 +2466,6 @@ extern "rust-intrinsic" { #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] -#[cfg(not(bootstrap))] #[rustc_nounwind] #[rustc_do_not_const_check] #[inline] @@ -2581,28 +2524,6 @@ extern "rust-intrinsic" { #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn black_box(dummy: T) -> T; - - #[rustc_nounwind] - #[cfg(bootstrap)] - pub fn vtable_size(ptr: *const ()) -> usize; - - /// `ptr` must point to a vtable. - /// The intrinsic will return the alignment stored in that vtable. - #[rustc_nounwind] - #[cfg(bootstrap)] - pub fn vtable_align(ptr: *const ()) -> usize; - - #[rustc_const_unstable(feature = "const_eval_select", issue = "none")] - #[rustc_safe_intrinsic] - #[cfg(bootstrap)] - pub fn const_eval_select( - arg: ARG, - called_in_const: F, - called_at_rt: G, - ) -> RET - where - G: FnOnce, - F: FnOnce; } /// Selects which function to call depending on the context. @@ -2637,11 +2558,9 @@ extern "rust-intrinsic" { /// #![feature(const_eval_select)] /// #![feature(core_intrinsics)] /// # #![allow(internal_features)] -/// # #![cfg_attr(bootstrap, allow(unused))] /// use std::intrinsics::const_eval_select; /// /// // Standard library -/// # #[cfg(not(bootstrap))] /// pub const fn inconsistent() -> i32 { /// fn runtime() -> i32 { 1 } /// const fn compiletime() -> i32 { 2 } @@ -2650,8 +2569,6 @@ extern "rust-intrinsic" { /// // and `runtime`. /// const_eval_select((), compiletime, runtime) /// } -/// # #[cfg(bootstrap)] -/// # pub const fn inconsistent() -> i32 { 0 } /// /// // User Crate /// const X: i32 = inconsistent(); @@ -2663,7 +2580,6 @@ extern "rust-intrinsic" { /// otherwise, that principle should not be violated. #[rustc_const_unstable(feature = "const_eval_select", issue = "none")] #[unstable(feature = "core_intrinsics", issue = "none")] -#[cfg(not(bootstrap))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn const_eval_select( @@ -2776,7 +2692,7 @@ pub const fn is_val_statically_known(_arg: T) -> bool { /// `x` and `y` are readable and writable as `T`, and non-overlapping. #[rustc_nounwind] #[inline] -#[cfg_attr(not(bootstrap), rustc_intrinsic)] +#[rustc_intrinsic] // This has fallback `const fn` MIR, so shouldn't need stability, see #122652 #[rustc_const_unstable(feature = "const_typed_swap", issue = "none")] pub const unsafe fn typed_swap(x: *mut T, y: *mut T) { @@ -2801,7 +2717,7 @@ pub const unsafe fn typed_swap(x: *mut T, y: *mut T) { #[rustc_const_unstable(feature = "const_ub_checks", issue = "none")] #[unstable(feature = "core_intrinsics", issue = "none")] #[inline(always)] -#[cfg_attr(not(bootstrap), rustc_intrinsic)] // just make it a regular fn in bootstrap +#[rustc_intrinsic] pub const fn ub_checks() -> bool { cfg!(debug_assertions) } @@ -2845,7 +2761,6 @@ pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] -#[cfg(not(bootstrap))] pub unsafe fn vtable_size(_ptr: *const ()) -> usize { unreachable!() } @@ -2856,7 +2771,6 @@ pub unsafe fn vtable_size(_ptr: *const ()) -> usize { #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] -#[cfg(not(bootstrap))] pub unsafe fn vtable_align(_ptr: *const ()) -> usize { unreachable!() } @@ -2871,7 +2785,6 @@ pub unsafe fn vtable_align(_ptr: *const ()) -> usize { #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] -#[cfg(not(bootstrap))] pub const fn aggregate_raw_ptr, D, M>(_data: D, _meta: M) -> P { // To implement a fallback we'd have to assume the layout of the pointer, // but the whole point of this intrinsic is that we shouldn't do that. diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index eeff4ec609a3..ceea67901294 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -540,12 +540,8 @@ extern "rust-intrinsic" { /// `T` must be a vector of pointers. /// /// `U` must be a vector of `usize` with the same length as `T`. - #[cfg(not(bootstrap))] #[rustc_nounwind] pub fn simd_expose_provenance(ptr: T) -> U; - #[cfg(bootstrap)] - #[rustc_nounwind] - pub fn simd_expose_addr(ptr: T) -> U; /// Create a vector of pointers from a vector of addresses. /// @@ -553,11 +549,7 @@ extern "rust-intrinsic" { /// /// `U` must be a vector of pointers, with the same length as `T`. #[rustc_nounwind] - #[cfg(not(bootstrap))] pub fn simd_with_exposed_provenance(addr: T) -> U; - #[rustc_nounwind] - #[cfg(bootstrap)] - pub fn simd_from_exposed_addr(addr: T) -> U; /// Swap bytes of each element. /// @@ -663,8 +655,3 @@ extern "rust-intrinsic" { #[rustc_nounwind] pub fn simd_flog(a: T) -> T; } - -#[cfg(bootstrap)] -pub use simd_expose_addr as simd_expose_provenance; -#[cfg(bootstrap)] -pub use simd_from_exposed_addr as simd_with_exposed_provenance; diff --git a/library/core/src/iter/sources/from_coroutine.rs b/library/core/src/iter/sources/from_coroutine.rs index 9bac9037a024..710ba504ded6 100644 --- a/library/core/src/iter/sources/from_coroutine.rs +++ b/library/core/src/iter/sources/from_coroutine.rs @@ -14,7 +14,7 @@ use crate::pin::Pin; /// #![feature(coroutines)] /// #![feature(iter_from_coroutine)] /// -/// let it = std::iter::from_coroutine(#[cfg_attr(not(bootstrap), coroutine)] || { +/// let it = std::iter::from_coroutine(#[coroutine] || { /// yield 1; /// yield 2; /// yield 3; diff --git a/library/core/src/iter/traits/marker.rs b/library/core/src/iter/traits/marker.rs index ad4d63d83b5b..2e756a6dd67c 100644 --- a/library/core/src/iter/traits/marker.rs +++ b/library/core/src/iter/traits/marker.rs @@ -28,7 +28,7 @@ pub unsafe trait TrustedFused {} #[rustc_unsafe_specialization_marker] // FIXME: this should be a #[marker] and have another blanket impl for T: TrustedFused // but that ICEs iter::Fuse specializations. -#[cfg_attr(not(bootstrap), lang = "fused_iterator")] +#[lang = "fused_iterator"] pub trait FusedIterator: Iterator {} #[stable(feature = "fused", since = "1.26.0")] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index cee3870c6292..5dcef6389544 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -90,7 +90,7 @@ ))] #![no_core] #![rustc_coherence_is_core] -#![cfg_attr(not(bootstrap), rustc_preserve_ub_checks)] +#![rustc_preserve_ub_checks] // // Lints: #![deny(rust_2021_incompatible_or_patterns)] @@ -109,7 +109,6 @@ // // Library features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(associated_type_bounds))] #![feature(array_ptr_get)] #![feature(asm_experimental_arch)] #![feature(char_indices_offset)] @@ -201,7 +200,6 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(inline_const))] #![feature(abi_unadjusted)] #![feature(adt_const_params)] #![feature(allow_internal_unsafe)] @@ -402,7 +400,6 @@ pub mod net; pub mod option; pub mod panic; pub mod panicking; -#[cfg(not(bootstrap))] #[unstable(feature = "core_pattern_types", issue = "none")] pub mod pat; pub mod pin; diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 6da05a1ca867..40a91689014b 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1715,7 +1715,6 @@ pub(crate) mod builtin { builtin # type_ascribe($expr, $ty) } - #[cfg(not(bootstrap))] /// Unstable placeholder for deref patterns. #[allow_internal_unstable(builtin_syntax)] #[unstable( diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index f50419dad208..77b1039039b1 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1234,18 +1234,9 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { - #[cfg(bootstrap)] - { - // For bootstrapping, just use built-in primitive shift. - // panicking is a legal manifestation of UB - self << rhs - } - #[cfg(not(bootstrap))] - { // SAFETY: the caller must uphold the safety contract for // `unchecked_shl`. unsafe { intrinsics::unchecked_shl(self, rhs) } - } } /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is @@ -1332,18 +1323,9 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { - #[cfg(bootstrap)] - { - // For bootstrapping, just use built-in primitive shift. - // panicking is a legal manifestation of UB - self >> rhs - } - #[cfg(not(bootstrap))] - { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_shr`. - unsafe { intrinsics::unchecked_shr(self, rhs) } - } + // SAFETY: the caller must uphold the safety contract for + // `unchecked_shr`. + unsafe { intrinsics::unchecked_shr(self, rhs) } } /// Checked absolute value. Computes `self.abs()`, returning `None` if diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index fca367876593..5d3ae7316b12 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -528,10 +528,7 @@ macro_rules! nonzero_integer { pub const fn leading_zeros(self) -> u32 { // SAFETY: since `self` cannot be zero, it is safe to call `ctlz_nonzero`. unsafe { - #[cfg(not(bootstrap))] - return intrinsics::ctlz_nonzero(self.get() as $UnsignedPrimitive); - #[cfg(bootstrap)] - return intrinsics::ctlz_nonzero(self.get() as $UnsignedPrimitive) as u32; + intrinsics::ctlz_nonzero(self.get() as $UnsignedPrimitive) } } @@ -557,10 +554,7 @@ macro_rules! nonzero_integer { pub const fn trailing_zeros(self) -> u32 { // SAFETY: since `self` cannot be zero, it is safe to call `cttz_nonzero`. unsafe { - #[cfg(not(bootstrap))] - return intrinsics::cttz_nonzero(self.get() as $UnsignedPrimitive); - #[cfg(bootstrap)] - return intrinsics::cttz_nonzero(self.get() as $UnsignedPrimitive) as u32; + intrinsics::cttz_nonzero(self.get() as $UnsignedPrimitive) } } diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index bb5113577c22..9effa279b48e 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -77,10 +77,7 @@ macro_rules! uint_impl { without modifying the original"] #[inline(always)] pub const fn count_ones(self) -> u32 { - #[cfg(not(bootstrap))] return intrinsics::ctpop(self as $ActualT); - #[cfg(bootstrap)] - return intrinsics::ctpop(self as $ActualT) as u32; } /// Returns the number of zeros in the binary representation of `self`. @@ -122,10 +119,7 @@ macro_rules! uint_impl { without modifying the original"] #[inline(always)] pub const fn leading_zeros(self) -> u32 { - #[cfg(not(bootstrap))] return intrinsics::ctlz(self as $ActualT); - #[cfg(bootstrap)] - return intrinsics::ctlz(self as $ActualT) as u32; } /// Returns the number of trailing zeros in the binary representation @@ -146,10 +140,7 @@ macro_rules! uint_impl { without modifying the original"] #[inline(always)] pub const fn trailing_zeros(self) -> u32 { - #[cfg(not(bootstrap))] return intrinsics::cttz(self); - #[cfg(bootstrap)] - return intrinsics::cttz(self) as u32; } /// Returns the number of leading ones in the binary representation of `self`. @@ -214,10 +205,7 @@ macro_rules! uint_impl { without modifying the original"] #[inline(always)] pub const fn rotate_left(self, n: u32) -> Self { - #[cfg(not(bootstrap))] return intrinsics::rotate_left(self, n); - #[cfg(bootstrap)] - return intrinsics::rotate_left(self, n as $SelfT); } /// Shifts the bits to the right by a specified amount, `n`, @@ -242,10 +230,7 @@ macro_rules! uint_impl { without modifying the original"] #[inline(always)] pub const fn rotate_right(self, n: u32) -> Self { - #[cfg(not(bootstrap))] return intrinsics::rotate_right(self, n); - #[cfg(bootstrap)] - return intrinsics::rotate_right(self, n as $SelfT); } /// Reverses the byte order of the integer. @@ -1324,18 +1309,9 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { - #[cfg(bootstrap)] - { - // For bootstrapping, just use built-in primitive shift. - // panicking is a legal manifestation of UB - self << rhs - } - #[cfg(not(bootstrap))] - { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_shl`. - unsafe { intrinsics::unchecked_shl(self, rhs) } - } + // SAFETY: the caller must uphold the safety contract for + // `unchecked_shl`. + unsafe { intrinsics::unchecked_shl(self, rhs) } } /// Checked shift right. Computes `self >> rhs`, returning `None` @@ -1422,18 +1398,9 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { - #[cfg(bootstrap)] - { - // For bootstrapping, just use built-in primitive shift. - // panicking is a legal manifestation of UB - self >> rhs - } - #[cfg(not(bootstrap))] - { // SAFETY: the caller must uphold the safety contract for // `unchecked_shr`. unsafe { intrinsics::unchecked_shr(self, rhs) } - } } /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if diff --git a/library/core/src/ops/coroutine.rs b/library/core/src/ops/coroutine.rs index 5250be15fe43..6a6c5db1ab11 100644 --- a/library/core/src/ops/coroutine.rs +++ b/library/core/src/ops/coroutine.rs @@ -46,7 +46,7 @@ pub enum CoroutineState { /// use std::pin::Pin; /// /// fn main() { -/// let mut coroutine = #[cfg_attr(not(bootstrap), coroutine)] || { +/// let mut coroutine = #[coroutine] || { /// yield 1; /// "foo" /// }; diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index 3795a81c2c15..9849410d484c 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -285,7 +285,7 @@ impl DerefMut for &mut T { /// is concerned. Calls to `deref`/`deref_mut`` must leave the pointer itself likewise /// unchanged. #[unstable(feature = "deref_pure_trait", issue = "87121")] -#[cfg_attr(not(bootstrap), lang = "deref_pure")] +#[lang = "deref_pure"] pub unsafe trait DerefPure {} #[unstable(feature = "deref_pure_trait", issue = "87121")] diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs index 1325d90e4f34..36ae581e3f72 100644 --- a/library/core/src/ops/drop.rs +++ b/library/core/src/ops/drop.rs @@ -240,7 +240,6 @@ pub trait Drop { } /// Fallback function to call surface level `Drop::drop` function -#[cfg(not(bootstrap))] #[allow(drop_bounds)] #[lang = "fallback_surface_drop"] pub(crate) fn fallback_surface_drop(x: &mut T) { diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs index 81d5e5c949ec..7bcfaadbe372 100644 --- a/library/core/src/ops/mod.rs +++ b/library/core/src/ops/mod.rs @@ -174,7 +174,6 @@ pub use self::deref::Receiver; #[stable(feature = "rust1", since = "1.0.0")] pub use self::drop::Drop; -#[cfg(not(bootstrap))] pub(crate) use self::drop::fallback_surface_drop; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 3ee56e6c5799..ca06e059b75a 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -156,7 +156,6 @@ pub const fn panic(expr: &'static str) -> ! { // reducing binary size impact. macro_rules! panic_const { ($($lang:ident = $message:expr,)+) => { - #[cfg(not(bootstrap))] pub mod panic_const { use super::*; diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index a11c6c742d7d..f7463d170fd8 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -1809,7 +1809,7 @@ impl DispatchFromDyn> for Pin where Ptr: DispatchFromDyn /// fn coroutine_fn() -> impl Coroutine /* not Unpin */ { /// // Allow coroutine to be self-referential (not `Unpin`) /// // vvvvvv so that locals can cross yield points. -/// #[cfg_attr(not(bootstrap), coroutine)] static || { +/// #[coroutine] static || { /// let foo = String::from("foo"); /// let foo_ref = &foo; // ------+ /// yield 0; // | <- crosses yield point! diff --git a/library/core/src/prelude/common.rs b/library/core/src/prelude/common.rs index b98f3a4659b1..afc6817aa1d2 100644 --- a/library/core/src/prelude/common.rs +++ b/library/core/src/prelude/common.rs @@ -97,7 +97,6 @@ pub use crate::macros::builtin::cfg_eval; )] pub use crate::macros::builtin::type_ascribe; -#[cfg(not(bootstrap))] #[unstable( feature = "deref_patterns", issue = "87121", diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index 1226c8e24194..eb815b6d822c 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -2,7 +2,6 @@ use crate::fmt; use crate::hash::{Hash, Hasher}; -#[cfg(not(bootstrap))] use crate::intrinsics::aggregate_raw_ptr; use crate::marker::Freeze; @@ -115,17 +114,7 @@ pub const fn from_raw_parts( data_pointer: *const (), metadata: ::Metadata, ) -> *const T { - #[cfg(bootstrap)] - { - // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T - // and PtrComponents have the same memory layouts. Only std can make this - // guarantee. - unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.const_ptr } - } - #[cfg(not(bootstrap))] - { - aggregate_raw_ptr(data_pointer, metadata) - } + aggregate_raw_ptr(data_pointer, metadata) } /// Performs the same functionality as [`from_raw_parts`], except that a @@ -139,17 +128,7 @@ pub const fn from_raw_parts_mut( data_pointer: *mut (), metadata: ::Metadata, ) -> *mut T { - #[cfg(bootstrap)] - { - // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T - // and PtrComponents have the same memory layouts. Only std can make this - // guarantee. - unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.mut_ptr } - } - #[cfg(not(bootstrap))] - { - aggregate_raw_ptr(data_pointer, metadata) - } + aggregate_raw_ptr(data_pointer, metadata) } #[repr(C)] diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index f12ab3d50cdd..5f3815859c8f 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1784,15 +1784,6 @@ pub(crate) const unsafe fn align_offset(p: *const T, a: usize) -> usiz assume, cttz_nonzero, exact_div, mul_with_overflow, unchecked_rem, unchecked_sub, wrapping_add, wrapping_mul, wrapping_sub, }; - #[cfg(bootstrap)] - const unsafe fn unchecked_shl(value: usize, shift: usize) -> usize { - value << shift - } - #[cfg(bootstrap)] - const unsafe fn unchecked_shr(value: usize, shift: usize) -> usize { - value >> shift - } - #[cfg(not(bootstrap))] use intrinsics::{unchecked_shl, unchecked_shr}; /// Calculate multiplicative modular inverse of `x` modulo `m`. diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 249b8ccb4374..232ec589093d 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -512,7 +512,6 @@ impl AtomicBool { /// /// ``` /// #![feature(atomic_from_mut)] - /// # #![cfg_attr(bootstrap, feature(inline_const))] /// use std::sync::atomic::{AtomicBool, Ordering}; /// /// let mut some_bools = [const { AtomicBool::new(false) }; 10]; @@ -1315,7 +1314,6 @@ impl AtomicPtr { /// /// ``` /// #![feature(atomic_from_mut)] - /// # #![cfg_attr(bootstrap, feature(inline_const))] /// use std::ptr::null_mut; /// use std::sync::atomic::{AtomicPtr, Ordering}; /// @@ -2306,7 +2304,6 @@ macro_rules! atomic_int { /// /// ``` /// #![feature(atomic_from_mut)] - /// # #![cfg_attr(bootstrap, feature(inline_const))] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let mut some_ints = [const { ", stringify!($atomic_type), "::new(0) }; 10];")] diff --git a/library/core/tests/intrinsics.rs b/library/core/tests/intrinsics.rs index eb1e1a0b9b1d..8b731cf5b25d 100644 --- a/library/core/tests/intrinsics.rs +++ b/library/core/tests/intrinsics.rs @@ -100,7 +100,6 @@ fn test_const_deallocate_at_runtime() { } } -#[cfg(not(bootstrap))] #[test] fn test_three_way_compare_in_const_contexts() { use core::cmp::Ordering::{self, *}; diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 8a35fdd1857d..797108a8425d 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -21,7 +21,7 @@ #![feature(const_pointer_is_aligned)] #![feature(const_ptr_as_ref)] #![feature(const_ptr_write)] -#![cfg_attr(not(bootstrap), feature(const_three_way_compare))] +#![feature(const_three_way_compare)] #![feature(const_trait_impl)] #![feature(const_likely)] #![feature(core_intrinsics)] @@ -46,7 +46,6 @@ #![feature(hasher_prefixfree_extras)] #![feature(hashmap_internals)] #![feature(try_find)] -#![cfg_attr(bootstrap, feature(inline_const))] #![feature(is_sorted)] #![feature(layout_for_ptr)] #![feature(pattern)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index fb63445c22a9..27b46b462044 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -224,7 +224,7 @@ `#![no_std]` or overriding this warning by enabling this feature." ) )] -#![cfg_attr(not(bootstrap), rustc_preserve_ub_checks)] +#![rustc_preserve_ub_checks] #![doc( html_playground_url = "https://play.rust-lang.org/", issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", @@ -592,7 +592,6 @@ pub mod net; pub mod num; pub mod os; pub mod panic; -#[cfg(not(bootstrap))] #[unstable(feature = "core_pattern_types", issue = "none")] pub mod pat; pub mod path; diff --git a/library/std/src/prelude/common.rs b/library/std/src/prelude/common.rs index f61e04e02b66..01936734d754 100644 --- a/library/std/src/prelude/common.rs +++ b/library/std/src/prelude/common.rs @@ -84,7 +84,6 @@ pub use core::prelude::v1::cfg_eval; )] pub use core::prelude::v1::type_ascribe; -#[cfg(not(bootstrap))] // Do not `doc(no_inline)` either. #[unstable( feature = "deref_patterns", diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 07488282983f..0ad6c959309a 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -2124,13 +2124,10 @@ impl<'a> Builder<'a> { // during incremental builds" heuristic for the standard library. rustflags.arg("-Zinline-mir"); - // FIXME: always pass this after the next `#[cfg(bootstrap)]` update. - if compiler.stage != 0 { - // Similarly, we need to keep debug info for functions inlined into other std functions, - // even if we're not going to output debuginfo for the crate we're currently building, - // so that it'll be available when downstream consumers of std try to use it. - rustflags.arg("-Zinline-mir-preserve-debug"); - } + // Similarly, we need to keep debug info for functions inlined into other std functions, + // even if we're not going to output debuginfo for the crate we're currently building, + // so that it'll be available when downstream consumers of std try to use it. + rustflags.arg("-Zinline-mir-preserve-debug"); } if self.config.rustc_parallel From e2eb053bba6fa585e64c6976660ed143ea8de930 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 2 May 2024 04:19:43 +0200 Subject: [PATCH 234/279] Slightly reformat !'s docs after applying github suggestions --- library/core/src/primitive_docs.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index d9c81239fc4b..2ca69d1faa2a 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -270,8 +270,8 @@ mod prim_bool {} /// /// # Never type fallback /// -/// When the compiler sees a value of type `!` in a [coercion site](https://doc.rust-lang.org/reference/type-coercions.html#coercion-sites), it implicitly inserts a coercion -/// to allow the type checker to infer any type: +/// When the compiler sees a value of type `!` in a [coercion site], it implicitly inserts a +/// coercion to allow the type checker to infer any type: /// /// ```rust,ignore (illustrative-and-has-placeholders) /// // this @@ -305,13 +305,15 @@ mod prim_bool {} /// /// This is what is known as "never type fallback". /// -/// Historically, the fallback type was [`()`], causing confusing behavior where `!` spontaneously coerced -/// to `()`, even when it would not infer `()` without the fallback. There are plans to -/// change it in the [2024 edition](https://doc.rust-lang.org/nightly/edition-guide/rust-2024/index.html) (and possibly in all editions on a later date); see +/// Historically, the fallback type was [`()`], causing confusing behavior where `!` spontaneously +/// coerced to `()`, even when it would not infer `()` without the fallback. There are plans to +/// change it in the [2024 edition] (and possibly in all editions on a later date); see /// [Tracking Issue for making `!` fall back to `!`][fallback-ti]. /// +/// [coercion site](https://doc.rust-lang.org/reference/type-coercions.html#coercion-sites) /// [`()`]: prim@unit /// [fallback-ti]: https://github.com/rust-lang/rust/issues/123748 +/// [2024 edition]: https://doc.rust-lang.org/nightly/edition-guide/rust-2024/index.html /// #[unstable(feature = "never_type", issue = "35121")] mod prim_never {} From 272413f458151978d7e2185e20d7d23ce81bf6e6 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Thu, 2 May 2024 04:45:45 +0200 Subject: [PATCH 235/279] allow or patterns for a high enough MSRV in `collapsible_match` --- clippy_lints/src/matches/collapsible_match.rs | 23 +++---- clippy_lints/src/matches/mod.rs | 23 +++++-- clippy_lints/src/matches/redundant_guards.rs | 7 +- tests/ui/collapsible_match.rs | 16 ++++- tests/ui/collapsible_match.stderr | 68 ++++++++++++------- 5 files changed, 88 insertions(+), 49 deletions(-) diff --git a/clippy_lints/src/matches/collapsible_match.rs b/clippy_lints/src/matches/collapsible_match.rs index 6746920edc51..90cfdecc1993 100644 --- a/clippy_lints/src/matches/collapsible_match.rs +++ b/clippy_lints/src/matches/collapsible_match.rs @@ -1,3 +1,4 @@ +use clippy_config::msrvs::Msrv; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::IfLetOrMatch; use clippy_utils::source::snippet; @@ -11,12 +12,12 @@ use rustc_hir::{Arm, Expr, HirId, Pat, PatKind}; use rustc_lint::LateContext; use rustc_span::Span; -use super::COLLAPSIBLE_MATCH; +use super::{pat_contains_disallowed_or, COLLAPSIBLE_MATCH}; -pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) { +pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], msrv: &Msrv) { if let Some(els_arm) = arms.iter().rfind(|arm| arm_is_wild_like(cx, arm)) { for arm in arms { - check_arm(cx, true, arm.pat, arm.body, arm.guard, Some(els_arm.body)); + check_arm(cx, true, arm.pat, arm.body, arm.guard, Some(els_arm.body), msrv); } } } @@ -26,8 +27,9 @@ pub(super) fn check_if_let<'tcx>( pat: &'tcx Pat<'_>, body: &'tcx Expr<'_>, else_expr: Option<&'tcx Expr<'_>>, + msrv: &Msrv, ) { - check_arm(cx, false, pat, body, None, else_expr); + check_arm(cx, false, pat, body, None, else_expr, msrv); } fn check_arm<'tcx>( @@ -37,6 +39,7 @@ fn check_arm<'tcx>( outer_then_body: &'tcx Expr<'tcx>, outer_guard: Option<&'tcx Expr<'tcx>>, outer_else_body: Option<&'tcx Expr<'tcx>>, + msrv: &Msrv, ) { let inner_expr = peel_blocks_with_stmt(outer_then_body); if let Some(inner) = IfLetOrMatch::parse(cx, inner_expr) @@ -57,7 +60,7 @@ fn check_arm<'tcx>( // match expression must be a local binding // match { .. } && let Some(binding_id) = path_to_local(peel_ref_operators(cx, inner_scrutinee)) - && !pat_contains_or(inner_then_pat) + && !pat_contains_disallowed_or(inner_then_pat, msrv) // the binding must come from the pattern of the containing match arm // .... => match { .. } && let (Some(binding_span), is_innermost_parent_pat_struct) @@ -142,13 +145,3 @@ fn find_pat_binding_and_is_innermost_parent_pat_struct(pat: &Pat<'_>, hir_id: Hi }); (span, is_innermost_parent_pat_struct) } - -fn pat_contains_or(pat: &Pat<'_>) -> bool { - let mut result = false; - pat.walk(|p| { - let is_or = matches!(p.kind, PatKind::Or(_)); - result |= is_or; - !is_or - }); - result -} diff --git a/clippy_lints/src/matches/mod.rs b/clippy_lints/src/matches/mod.rs index fae2c4e4af92..ee9f48d71ad8 100644 --- a/clippy_lints/src/matches/mod.rs +++ b/clippy_lints/src/matches/mod.rs @@ -27,7 +27,7 @@ mod wild_in_or_pats; use clippy_config::msrvs::{self, Msrv}; use clippy_utils::source::walk_span_to_context; use clippy_utils::{higher, in_constant, is_direct_expn_of, is_span_match, span_contains_cfg}; -use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat}; +use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat, PatKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::impl_lint_pass; @@ -1040,7 +1040,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches { significant_drop_in_scrutinee::check(cx, expr, ex, arms, source); } - collapsible_match::check_match(cx, arms); + collapsible_match::check_match(cx, arms, &self.msrv); if !from_expansion { // These don't depend on a relationship between multiple arms match_wild_err_arm::check(cx, ex, arms); @@ -1066,7 +1066,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches { needless_match::check_match(cx, ex, arms, expr); match_on_vec_items::check(cx, ex); match_str_case_mismatch::check(cx, ex, arms); - redundant_guards::check(cx, arms); + redundant_guards::check(cx, arms, &self.msrv); if !in_constant(cx, expr.hir_id) { manual_unwrap_or::check(cx, expr, ex, arms); @@ -1083,7 +1083,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches { match_ref_pats::check(cx, ex, arms.iter().map(|el| el.pat), expr); } } else if let Some(if_let) = higher::IfLet::hir(cx, expr) { - collapsible_match::check_if_let(cx, if_let.let_pat, if_let.if_then, if_let.if_else); + collapsible_match::check_if_let(cx, if_let.let_pat, if_let.if_then, if_let.if_else, &self.msrv); if !from_expansion { if let Some(else_expr) = if_let.if_else { if self.msrv.meets(msrvs::MATCHES_MACRO) { @@ -1195,3 +1195,18 @@ fn contains_cfg_arm(cx: &LateContext<'_>, e: &Expr<'_>, scrutinee: &Expr<'_>, ar Err(()) => true, } } + +/// Checks if `pat` contains OR patterns that cannot be nested due to a too low MSRV. +fn pat_contains_disallowed_or(pat: &Pat<'_>, msrv: &Msrv) -> bool { + if msrv.meets(msrvs::OR_PATTERNS) { + return false; + } + + let mut result = false; + pat.walk(|p| { + let is_or = matches!(p.kind, PatKind::Or(_)); + result |= is_or; + !is_or + }); + result +} diff --git a/clippy_lints/src/matches/redundant_guards.rs b/clippy_lints/src/matches/redundant_guards.rs index 50cbccc39683..984aa3d73708 100644 --- a/clippy_lints/src/matches/redundant_guards.rs +++ b/clippy_lints/src/matches/redundant_guards.rs @@ -1,3 +1,4 @@ +use clippy_config::msrvs::Msrv; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet; use clippy_utils::visitors::{for_each_expr, is_local_used}; @@ -12,9 +13,9 @@ use rustc_span::{Span, Symbol}; use std::borrow::Cow; use std::ops::ControlFlow; -use super::REDUNDANT_GUARDS; +use super::{pat_contains_disallowed_or, REDUNDANT_GUARDS}; -pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) { +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: &Msrv) { for outer_arm in arms { let Some(guard) = outer_arm.guard else { continue; @@ -35,6 +36,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) { MatchSource::Normal, ) = guard.kind && let Some(binding) = get_pat_binding(cx, scrutinee, outer_arm) + && !pat_contains_disallowed_or(&arm.pat, msrv) { let pat_span = match (arm.pat.kind, binding.byref_ident) { (PatKind::Ref(pat, _), Some(_)) => pat.span, @@ -53,6 +55,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) { // `Some(x) if let Some(2) = x` else if let ExprKind::Let(let_expr) = guard.kind && let Some(binding) = get_pat_binding(cx, let_expr.init, outer_arm) + && !pat_contains_disallowed_or(&let_expr.pat, msrv) { let pat_span = match (let_expr.pat.kind, binding.byref_ident) { (PatKind::Ref(pat, _), Some(_)) => pat.span, diff --git a/tests/ui/collapsible_match.rs b/tests/ui/collapsible_match.rs index 7501fd2b0bd9..2264b560791a 100644 --- a/tests/ui/collapsible_match.rs +++ b/tests/ui/collapsible_match.rs @@ -4,7 +4,8 @@ clippy::needless_return, clippy::no_effect, clippy::single_match, - clippy::uninlined_format_args + clippy::uninlined_format_args, + clippy::let_unit_value )] fn lint_cases(opt_opt: Option>, res_opt: Result, String>) { @@ -238,13 +239,22 @@ fn negative_cases(res_opt: Result, String>, res_res: Result return, } - match make::>>() { + #[clippy::msrv = "1.52.0"] + let _ = match make::>>() { Some(val) => match val { E::A(val) | E::B(val) => foo(val), _ => return, }, _ => return, - } + }; + #[clippy::msrv = "1.53.0"] + let _ = match make::>>() { + Some(val) => match val { + E::A(val) | E::B(val) => foo(val), + _ => return, + }, + _ => return, + }; if let Ok(val) = res_opt { if let Some(n) = val { let _ = || { diff --git a/tests/ui/collapsible_match.stderr b/tests/ui/collapsible_match.stderr index 46b484ab05c4..01944baee79a 100644 --- a/tests/ui/collapsible_match.stderr +++ b/tests/ui/collapsible_match.stderr @@ -1,5 +1,5 @@ error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:13:20 + --> tests/ui/collapsible_match.rs:14:20 | LL | Ok(val) => match val { | ____________________^ @@ -10,7 +10,7 @@ LL | | }, | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:13:12 + --> tests/ui/collapsible_match.rs:14:12 | LL | Ok(val) => match val { | ^^^ replace this binding @@ -21,7 +21,7 @@ LL | Some(n) => foo(n), = help: to override `-D warnings` add `#[allow(clippy::collapsible_match)]` error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:23:20 + --> tests/ui/collapsible_match.rs:24:20 | LL | Ok(val) => match val { | ____________________^ @@ -32,7 +32,7 @@ LL | | }, | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:23:12 + --> tests/ui/collapsible_match.rs:24:12 | LL | Ok(val) => match val { | ^^^ replace this binding @@ -41,7 +41,7 @@ LL | Some(n) => foo(n), | ^^^^^^^ with this pattern error: this `if let` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:33:9 + --> tests/ui/collapsible_match.rs:34:9 | LL | / if let Some(n) = val { LL | | @@ -50,7 +50,7 @@ LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:32:15 + --> tests/ui/collapsible_match.rs:33:15 | LL | if let Ok(val) = res_opt { | ^^^ replace this binding @@ -58,7 +58,7 @@ LL | if let Some(n) = val { | ^^^^^^^ with this pattern error: this `if let` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:41:9 + --> tests/ui/collapsible_match.rs:42:9 | LL | / if let Some(n) = val { LL | | @@ -69,7 +69,7 @@ LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:40:15 + --> tests/ui/collapsible_match.rs:41:15 | LL | if let Ok(val) = res_opt { | ^^^ replace this binding @@ -77,7 +77,7 @@ LL | if let Some(n) = val { | ^^^^^^^ with this pattern error: this `match` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:53:9 + --> tests/ui/collapsible_match.rs:54:9 | LL | / match val { LL | | @@ -87,7 +87,7 @@ LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:52:15 + --> tests/ui/collapsible_match.rs:53:15 | LL | if let Ok(val) = res_opt { | ^^^ replace this binding @@ -96,7 +96,7 @@ LL | Some(n) => foo(n), | ^^^^^^^ with this pattern error: this `if let` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:63:13 + --> tests/ui/collapsible_match.rs:64:13 | LL | / if let Some(n) = val { LL | | @@ -105,7 +105,7 @@ LL | | } | |_____________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:62:12 + --> tests/ui/collapsible_match.rs:63:12 | LL | Ok(val) => { | ^^^ replace this binding @@ -113,7 +113,7 @@ LL | if let Some(n) = val { | ^^^^^^^ with this pattern error: this `match` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:73:9 + --> tests/ui/collapsible_match.rs:74:9 | LL | / match val { LL | | @@ -123,7 +123,7 @@ LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:72:15 + --> tests/ui/collapsible_match.rs:73:15 | LL | if let Ok(val) = res_opt { | ^^^ replace this binding @@ -132,7 +132,7 @@ LL | Some(n) => foo(n), | ^^^^^^^ with this pattern error: this `if let` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:85:13 + --> tests/ui/collapsible_match.rs:86:13 | LL | / if let Some(n) = val { LL | | @@ -143,7 +143,7 @@ LL | | } | |_____________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:84:12 + --> tests/ui/collapsible_match.rs:85:12 | LL | Ok(val) => { | ^^^ replace this binding @@ -151,7 +151,7 @@ LL | if let Some(n) = val { | ^^^^^^^ with this pattern error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:97:20 + --> tests/ui/collapsible_match.rs:98:20 | LL | Ok(val) => match val { | ____________________^ @@ -162,7 +162,7 @@ LL | | }, | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:97:12 + --> tests/ui/collapsible_match.rs:98:12 | LL | Ok(val) => match val { | ^^^ replace this binding @@ -171,7 +171,7 @@ LL | Some(n) => foo(n), | ^^^^^^^ with this pattern error: this `match` can be collapsed into the outer `match` - --> tests/ui/collapsible_match.rs:107:22 + --> tests/ui/collapsible_match.rs:108:22 | LL | Some(val) => match val { | ______________________^ @@ -182,7 +182,7 @@ LL | | }, | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:107:14 + --> tests/ui/collapsible_match.rs:108:14 | LL | Some(val) => match val { | ^^^ replace this binding @@ -190,8 +190,26 @@ LL | LL | Some(n) => foo(n), | ^^^^^^^ with this pattern +error: this `match` can be collapsed into the outer `match` + --> tests/ui/collapsible_match.rs:252:22 + | +LL | Some(val) => match val { + | ______________________^ +LL | | E::A(val) | E::B(val) => foo(val), +LL | | _ => return, +LL | | }, + | |_________^ + | +help: the outer pattern can be modified to include the inner pattern + --> tests/ui/collapsible_match.rs:252:14 + | +LL | Some(val) => match val { + | ^^^ replace this binding +LL | E::A(val) | E::B(val) => foo(val), + | ^^^^^^^^^^^^^^^^^^^^^ with this pattern + error: this `if let` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:273:9 + --> tests/ui/collapsible_match.rs:283:9 | LL | / if let Some(u) = a { LL | | @@ -200,7 +218,7 @@ LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:272:27 + --> tests/ui/collapsible_match.rs:282:27 | LL | if let Issue9647::A { a, .. } = x { | ^ replace this binding @@ -208,7 +226,7 @@ LL | if let Some(u) = a { | ^^^^^^^ with this pattern, prefixed by a: error: this `if let` can be collapsed into the outer `if let` - --> tests/ui/collapsible_match.rs:282:9 + --> tests/ui/collapsible_match.rs:292:9 | LL | / if let Some(u) = a { LL | | @@ -217,12 +235,12 @@ LL | | } | |_________^ | help: the outer pattern can be modified to include the inner pattern - --> tests/ui/collapsible_match.rs:281:35 + --> tests/ui/collapsible_match.rs:291:35 | LL | if let Issue9647::A { a: Some(a), .. } = x { | ^ replace this binding LL | if let Some(u) = a { | ^^^^^^^ with this pattern -error: aborting due to 12 previous errors +error: aborting due to 13 previous errors From 790fb9396a14e4686ff4b5ab88d91577cffe1d44 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Thu, 2 May 2024 04:58:28 +0200 Subject: [PATCH 236/279] check for `matches!` macro directly in `redundant_guards` --- clippy_lints/src/matches/redundant_guards.rs | 24 ++++---------- tests/ui/redundant_guards.fixed | 12 +++++++ tests/ui/redundant_guards.rs | 12 +++++++ tests/ui/redundant_guards.stderr | 34 ++++++++++---------- 4 files changed, 48 insertions(+), 34 deletions(-) diff --git a/clippy_lints/src/matches/redundant_guards.rs b/clippy_lints/src/matches/redundant_guards.rs index 984aa3d73708..a75cf37945f7 100644 --- a/clippy_lints/src/matches/redundant_guards.rs +++ b/clippy_lints/src/matches/redundant_guards.rs @@ -1,15 +1,16 @@ use clippy_config::msrvs::Msrv; use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::macros::matching_root_macro_call; use clippy_utils::source::snippet; use clippy_utils::visitors::{for_each_expr, is_local_used}; use clippy_utils::{in_constant, path_to_local}; use rustc_ast::{BorrowKind, LitKind}; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{Arm, BinOpKind, Expr, ExprKind, MatchSource, Node, Pat, PatKind, UnOp}; +use rustc_hir::{Arm, BinOpKind, Expr, ExprKind, MatchSource, Node, PatKind, UnOp}; use rustc_lint::LateContext; use rustc_span::symbol::Ident; -use rustc_span::{Span, Symbol}; +use rustc_span::{sym, Span, Symbol}; use std::borrow::Cow; use std::ops::ControlFlow; @@ -22,21 +23,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: }; // `Some(x) if matches!(x, y)` - if let ExprKind::Match( - scrutinee, - [ - arm, - Arm { - pat: Pat { - kind: PatKind::Wild, .. - }, - .. - }, - ], - MatchSource::Normal, - ) = guard.kind + if let ExprKind::Match(scrutinee, [arm, _], MatchSource::Normal) = guard.kind + && matching_root_macro_call(cx, guard.span, sym::matches_macro).is_some() && let Some(binding) = get_pat_binding(cx, scrutinee, outer_arm) - && !pat_contains_disallowed_or(&arm.pat, msrv) + && !pat_contains_disallowed_or(arm.pat, msrv) { let pat_span = match (arm.pat.kind, binding.byref_ident) { (PatKind::Ref(pat, _), Some(_)) => pat.span, @@ -55,7 +45,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: // `Some(x) if let Some(2) = x` else if let ExprKind::Let(let_expr) = guard.kind && let Some(binding) = get_pat_binding(cx, let_expr.init, outer_arm) - && !pat_contains_disallowed_or(&let_expr.pat, msrv) + && !pat_contains_disallowed_or(let_expr.pat, msrv) { let pat_span = match (let_expr.pat.kind, binding.byref_ident) { (PatKind::Ref(pat, _), Some(_)) => pat.span, diff --git a/tests/ui/redundant_guards.fixed b/tests/ui/redundant_guards.fixed index ded91e083769..ed4b1c219150 100644 --- a/tests/ui/redundant_guards.fixed +++ b/tests/ui/redundant_guards.fixed @@ -136,6 +136,18 @@ fn f(s: Option) { } } +fn not_matches() { + match Some(42) { + // The pattern + guard is not equivalent to `Some(42)` because of the `panic!` + Some(v) + if match v { + 42 => true, + _ => panic!(), + } => {}, + _ => {}, + } +} + struct S { a: usize, } diff --git a/tests/ui/redundant_guards.rs b/tests/ui/redundant_guards.rs index 2aaa2ace3982..adbc4ed16cd7 100644 --- a/tests/ui/redundant_guards.rs +++ b/tests/ui/redundant_guards.rs @@ -136,6 +136,18 @@ fn f(s: Option) { } } +fn not_matches() { + match Some(42) { + // The pattern + guard is not equivalent to `Some(42)` because of the `panic!` + Some(v) + if match v { + 42 => true, + _ => panic!(), + } => {}, + _ => {}, + } +} + struct S { a: usize, } diff --git a/tests/ui/redundant_guards.stderr b/tests/ui/redundant_guards.stderr index 01ca91fcd09e..fd12e0832823 100644 --- a/tests/ui/redundant_guards.stderr +++ b/tests/ui/redundant_guards.stderr @@ -132,7 +132,7 @@ LL + 1 => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:174:28 + --> tests/ui/redundant_guards.rs:186:28 | LL | Some(ref x) if x == &1 => {}, | ^^^^^^^ @@ -144,7 +144,7 @@ LL + Some(1) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:175:28 + --> tests/ui/redundant_guards.rs:187:28 | LL | Some(ref x) if &1 == x => {}, | ^^^^^^^ @@ -156,7 +156,7 @@ LL + Some(1) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:176:28 + --> tests/ui/redundant_guards.rs:188:28 | LL | Some(ref x) if let &2 = x => {}, | ^^^^^^^^^^ @@ -168,7 +168,7 @@ LL + Some(2) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:177:28 + --> tests/ui/redundant_guards.rs:189:28 | LL | Some(ref x) if matches!(x, &3) => {}, | ^^^^^^^^^^^^^^^ @@ -180,7 +180,7 @@ LL + Some(3) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:197:32 + --> tests/ui/redundant_guards.rs:209:32 | LL | B { ref c, .. } if c == &1 => {}, | ^^^^^^^ @@ -192,7 +192,7 @@ LL + B { c: 1, .. } => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:198:32 + --> tests/ui/redundant_guards.rs:210:32 | LL | B { ref c, .. } if &1 == c => {}, | ^^^^^^^ @@ -204,7 +204,7 @@ LL + B { c: 1, .. } => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:199:32 + --> tests/ui/redundant_guards.rs:211:32 | LL | B { ref c, .. } if let &1 = c => {}, | ^^^^^^^^^^ @@ -216,7 +216,7 @@ LL + B { c: 1, .. } => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:200:32 + --> tests/ui/redundant_guards.rs:212:32 | LL | B { ref c, .. } if matches!(c, &1) => {}, | ^^^^^^^^^^^^^^^ @@ -228,7 +228,7 @@ LL + B { c: 1, .. } => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:210:26 + --> tests/ui/redundant_guards.rs:222:26 | LL | Some(Some(x)) if x.is_empty() => {}, | ^^^^^^^^^^^^ @@ -240,7 +240,7 @@ LL + Some(Some("")) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:221:26 + --> tests/ui/redundant_guards.rs:233:26 | LL | Some(Some(x)) if x.is_empty() => {}, | ^^^^^^^^^^^^ @@ -252,7 +252,7 @@ LL + Some(Some([])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:226:26 + --> tests/ui/redundant_guards.rs:238:26 | LL | Some(Some(x)) if x.is_empty() => {}, | ^^^^^^^^^^^^ @@ -264,7 +264,7 @@ LL + Some(Some([])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:237:26 + --> tests/ui/redundant_guards.rs:249:26 | LL | Some(Some(x)) if x.starts_with(&[]) => {}, | ^^^^^^^^^^^^^^^^^^ @@ -276,7 +276,7 @@ LL + Some(Some([..])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:242:26 + --> tests/ui/redundant_guards.rs:254:26 | LL | Some(Some(x)) if x.starts_with(&[1]) => {}, | ^^^^^^^^^^^^^^^^^^^ @@ -288,7 +288,7 @@ LL + Some(Some([1, ..])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:247:26 + --> tests/ui/redundant_guards.rs:259:26 | LL | Some(Some(x)) if x.starts_with(&[1, 2]) => {}, | ^^^^^^^^^^^^^^^^^^^^^^ @@ -300,7 +300,7 @@ LL + Some(Some([1, 2, ..])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:252:26 + --> tests/ui/redundant_guards.rs:264:26 | LL | Some(Some(x)) if x.ends_with(&[1, 2]) => {}, | ^^^^^^^^^^^^^^^^^^^^ @@ -312,7 +312,7 @@ LL + Some(Some([.., 1, 2])) => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:274:18 + --> tests/ui/redundant_guards.rs:286:18 | LL | y if y.is_empty() => {}, | ^^^^^^^^^^^^ @@ -324,7 +324,7 @@ LL + "" => {}, | error: redundant guard - --> tests/ui/redundant_guards.rs:293:22 + --> tests/ui/redundant_guards.rs:305:22 | LL | y if y.is_empty() => {}, | ^^^^^^^^^^^^ From 44988e25770e87949e282f606dee702906bd2eed Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 1 May 2024 23:23:00 -0400 Subject: [PATCH 237/279] Workaround rustfmt bug replacing type ascription --- library/core/src/macros/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 40a91689014b..2ddedfa37fe2 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1711,6 +1711,7 @@ pub(crate) mod builtin { issue = "23416", reason = "placeholder syntax for type ascription" )] + #[rustfmt::skip] pub macro type_ascribe($expr:expr, $ty:ty) { builtin # type_ascribe($expr, $ty) } From 5e05821af33d98d06242940417de6c915950c391 Mon Sep 17 00:00:00 2001 From: "Christopher B. Speir" Date: Wed, 1 May 2024 22:23:31 -0500 Subject: [PATCH 238/279] Remove clippy_utils::paths::{SLICE_GET, STR_BYTES} Both clippy_utils::paths::SLICE_GET and clippy_utils::paths::STR_BYTES are dead_code and can therefore be removed. --- clippy_utils/src/paths.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index 0e26b3bfd624..2836df0926d4 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -73,7 +73,6 @@ pub const REGEX_NEW: [&str; 3] = ["regex", "Regex", "new"]; pub const REGEX_SET_NEW: [&str; 3] = ["regex", "RegexSet", "new"]; pub const SERDE_DESERIALIZE: [&str; 3] = ["serde", "de", "Deserialize"]; pub const SERDE_DE_VISITOR: [&str; 3] = ["serde", "de", "Visitor"]; -pub const SLICE_GET: [&str; 4] = ["core", "slice", "", "get"]; pub const SLICE_INTO_VEC: [&str; 4] = ["alloc", "slice", "", "into_vec"]; pub const SLICE_INTO: [&str; 4] = ["core", "slice", "", "iter"]; pub const STD_IO_SEEK_FROM_CURRENT: [&str; 4] = ["std", "io", "SeekFrom", "Current"]; @@ -81,7 +80,6 @@ pub const STD_IO_SEEKFROM_START: [&str; 4] = ["std", "io", "SeekFrom", "Start"]; pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"]; pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"]; pub const STRING_NEW: [&str; 4] = ["alloc", "string", "String", "new"]; -pub const STR_BYTES: [&str; 4] = ["core", "str", "", "bytes"]; pub const STR_CHARS: [&str; 4] = ["core", "str", "", "chars"]; pub const STR_ENDS_WITH: [&str; 4] = ["core", "str", "", "ends_with"]; pub const STR_LEN: [&str; 4] = ["core", "str", "", "len"]; From e18b6e819e703a6f66c93e803655b62146f9d018 Mon Sep 17 00:00:00 2001 From: Waffle Maybe Date: Thu, 2 May 2024 06:04:16 +0200 Subject: [PATCH 239/279] fixup links in never type docs Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com> --- library/core/src/primitive_docs.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 2ca69d1faa2a..18a9503cfd2f 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -310,10 +310,10 @@ mod prim_bool {} /// change it in the [2024 edition] (and possibly in all editions on a later date); see /// [Tracking Issue for making `!` fall back to `!`][fallback-ti]. /// -/// [coercion site](https://doc.rust-lang.org/reference/type-coercions.html#coercion-sites) +/// [coercion site]: /// [`()`]: prim@unit -/// [fallback-ti]: https://github.com/rust-lang/rust/issues/123748 -/// [2024 edition]: https://doc.rust-lang.org/nightly/edition-guide/rust-2024/index.html +/// [fallback-ti]: +/// [2024 edition]: /// #[unstable(feature = "never_type", issue = "35121")] mod prim_never {} From 9af3b1eff470b7ff52593b4462846705f8ffe470 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Thu, 2 May 2024 06:33:05 +0200 Subject: [PATCH 240/279] library/std: Remove unused `gimli-symbolize` feature library/backtrace also declares a feature called `gimli-symbolize` which appear used, but the feature in std with the same name is unused, so remove it. --- library/std/Cargo.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index cba9ff4485d0..52729ba1f845 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -64,12 +64,10 @@ r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std'] } [features] backtrace = [ - "gimli-symbolize", 'addr2line/rustc-dep-of-std', 'object/rustc-dep-of-std', 'miniz_oxide/rustc-dep-of-std', ] -gimli-symbolize = [] panic-unwind = ["panic_unwind"] profiler = ["profiler_builtins"] From 5c23f138dd5217e9b7cef3717540f05d76d7ce3d Mon Sep 17 00:00:00 2001 From: Fridtjof Stoldt Date: Mon, 29 Apr 2024 22:15:05 +0200 Subject: [PATCH 241/279] Apply suggestions from code review <3 Co-authored-by: Timo <30553356+y21@users.noreply.github.com> --- CHANGELOG.md | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d908ed43cfae..9c9ea1140814 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,14 +14,6 @@ Current stable, released 2024-05-02 [View all 112 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-01-26T05%3A46%3A23Z..2024-03-07T16%3A25%3A52Z+base%3Amaster) -### Important Changes - -* In a few versions, `cargo-clippy` will now no longer ignore the first argument. - Passing in `clippy` as the first argument like cargo does will continue to work. - However, arguments like `--fix` will soon issue a warning and will no longer be. - `cargo clippy` (without `-`!) is unaffected by this change. - [#9461](https://github.com/rust-lang/rust-clippy/pull/9461) - ### New Lints * [`assigning_clones`] @@ -51,11 +43,6 @@ Current stable, released 2024-05-02 * [`incompatible_msrv`] [#12160](https://github.com/rust-lang/rust-clippy/pull/12160) -### Moves and Deprecations - -* Moved [`mixed_attributes_style`] to `style` (Remains warn-by-default) - [#12572](https://github.com/rust-lang/rust-clippy/pull/12572) - ### Enhancements * [`thread_local_initializer_can_be_made_const`]: Now checks the [`msrv`] configuration @@ -67,9 +54,9 @@ Current stable, released 2024-05-02 ### ICE Fixes -* [`ptr_as_ptr`]: No longer ICEs on types from other crates +* [`ptr_as_ptr`]: No longer ICEs when the cast source is a function call to a local variable [#12617](https://github.com/rust-lang/rust-clippy/pull/12617) -* [`cast_sign_loss`]: Avoids an infinit loop when casting two changed `.unwrap()` calls +* [`cast_sign_loss`]: Avoids an infinite loop when casting two chained `.unwrap()` calls [#12508](https://github.com/rust-lang/rust-clippy/pull/12508) ## Rust 1.77 From dcfc3b5de1375c6984e8d3f829d50b940e5bab07 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 2 May 2024 12:44:40 +0200 Subject: [PATCH 242/279] Bump ui_test to 0.23 --- Cargo.toml | 2 +- tests/compile-test.rs | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 43f20ecedc21..bbd8ccb88b4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ color-print = "0.3.4" anstream = "0.6.0" [dev-dependencies] -ui_test = "0.22.2" +ui_test = "0.23" regex = "1.5.5" toml = "0.7.3" walkdir = "2.3" diff --git a/tests/compile-test.rs b/tests/compile-test.rs index 32a31f5e0823..b06a11702ec8 100644 --- a/tests/compile-test.rs +++ b/tests/compile-test.rs @@ -4,6 +4,7 @@ #![warn(rust_2018_idioms, unused_lifetimes)] #![allow(unused_extern_crates)] +use ui_test::custom_flags::rustfix::RustfixMode; use ui_test::spanned::Spanned; use ui_test::{status_emitter, Args, CommandBuilder, Config, Match, Mode, OutputConflictHandling}; @@ -122,10 +123,11 @@ fn base_config(test_dir: &str) -> (Config, Args) { out_dir: target_dir.join("ui_test"), ..Config::rustc(Path::new("tests").join(test_dir)) }; - config.comment_defaults.base().mode = Some(Spanned::dummy(Mode::Yolo { - rustfix: ui_test::RustfixMode::Everything, - })) - .into(); + config.comment_defaults.base().mode = Some(Spanned::dummy(Mode::Yolo)).into(); + config + .comment_defaults + .base() + .set_custom("rustfix", RustfixMode::Everything); config.comment_defaults.base().diagnostic_code_prefix = Some(Spanned::dummy("clippy::".into())).into(); config.with_args(&args); let current_exe_path = env::current_exe().unwrap(); @@ -235,13 +237,12 @@ fn run_ui_cargo() { .push(("RUSTFLAGS".into(), Some("-Dwarnings".into()))); // We need to do this while we still have a rustc in the `program` field. config.fill_host_and_target().unwrap(); - config.dependencies_crate_manifest_path = None; config.program.program.set_file_name(if cfg!(windows) { "cargo-clippy.exe" } else { "cargo-clippy" }); - config.comment_defaults.base().edition = Default::default(); + config.comment_defaults.base().custom.clear(); config .comment_defaults From 76b95fd2492389714e132dbd6b20142128cbe747 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 2 May 2024 14:21:19 +0200 Subject: [PATCH 243/279] Bump Clippy version -> 0.1.80 --- Cargo.toml | 2 +- clippy_config/Cargo.toml | 2 +- clippy_lints/Cargo.toml | 2 +- clippy_utils/Cargo.toml | 2 +- declare_clippy_lint/Cargo.toml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 43f20ecedc21..a932cc6e5e4b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.1.79" +version = "0.1.80" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/clippy_config/Cargo.toml b/clippy_config/Cargo.toml index 8ba2ab566256..7f7dc9d6cfb0 100644 --- a/clippy_config/Cargo.toml +++ b/clippy_config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_config" -version = "0.1.79" +version = "0.1.80" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index 1d954607eee8..5e3a119337cc 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_lints" -version = "0.1.79" +version = "0.1.80" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml index d2bb719a517f..ab883c25338b 100644 --- a/clippy_utils/Cargo.toml +++ b/clippy_utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_utils" -version = "0.1.79" +version = "0.1.80" edition = "2021" publish = false diff --git a/declare_clippy_lint/Cargo.toml b/declare_clippy_lint/Cargo.toml index 9a3a41e1d1ea..c8c734c3a7c9 100644 --- a/declare_clippy_lint/Cargo.toml +++ b/declare_clippy_lint/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "declare_clippy_lint" -version = "0.1.79" +version = "0.1.80" edition = "2021" publish = false From d878e0e8eedd18b03339435d983f04f202e83949 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 2 May 2024 14:21:32 +0200 Subject: [PATCH 244/279] Bump nightly version -> 2024-05-02 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 521c0d12983d..055f305eb8e1 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-04-18" +channel = "nightly-2024-05-02" components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] From e395dc9000b6f19aae52584c97b83b40e7e3a556 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 2 May 2024 17:27:08 +0200 Subject: [PATCH 245/279] Update Cargo.lock --- Cargo.lock | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca69536855ec..7e4db4fdd53e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -120,6 +120,16 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "annotate-snippets" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5a59f105fb9635e9eebdc1e29d53e764fa5795b9cf899a638a53e61567ef61" +dependencies = [ + "anstyle", + "unicode-width", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -574,7 +584,7 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "clippy" -version = "0.1.79" +version = "0.1.80" dependencies = [ "anstream", "clippy_config", @@ -595,13 +605,13 @@ dependencies = [ "termize", "tokio", "toml 0.7.8", - "ui_test 0.22.3", + "ui_test 0.23.0", "walkdir", ] [[package]] name = "clippy_config" -version = "0.1.79" +version = "0.1.80" dependencies = [ "rustc-semver", "serde", @@ -624,7 +634,7 @@ dependencies = [ [[package]] name = "clippy_lints" -version = "0.1.79" +version = "0.1.80" dependencies = [ "arrayvec", "cargo_metadata 0.18.1", @@ -649,7 +659,7 @@ dependencies = [ [[package]] name = "clippy_utils" -version = "0.1.79" +version = "0.1.80" dependencies = [ "arrayvec", "clippy_config", @@ -968,7 +978,7 @@ checksum = "a0afaad2b26fa326569eb264b1363e8ae3357618c43982b3f285f0774ce76b69" [[package]] name = "declare_clippy_lint" -version = "0.1.79" +version = "0.1.80" dependencies = [ "itertools 0.12.1", "quote", @@ -5160,9 +5170,9 @@ dependencies = [ [[package]] name = "spanned" -version = "0.1.6" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad48ded9f0734eca7058107cc170767b8758e41e4088fb0020e7ff7ec6b0d92d" +checksum = "ccdf4f5590b7e6fbd4f2e80d442789079a6fff7c12ef921a9de358b7b353098e" dependencies = [ "bstr", "color-eyre", @@ -5900,11 +5910,11 @@ dependencies = [ [[package]] name = "ui_test" -version = "0.22.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa577a42db0e211a73c069d7dbcae54bc7473a7c5535a564842cbd8a13c0441e" +checksum = "29e5f4ffcbab82453958fbf59990e981b8e8a177dcd60c2bd8f9b52c3036a6e1" dependencies = [ - "annotate-snippets 0.10.2", + "annotate-snippets 0.11.2", "anyhow", "bstr", "cargo-platform", @@ -5919,7 +5929,7 @@ dependencies = [ "prettydiff", "regex", "rustc_version", - "rustfix 0.6.1", + "rustfix 0.8.1", "serde", "serde_json", "spanned", From c4e882fd993d575d65e841da02161263c0ff2d16 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 2 May 2024 15:44:05 +0000 Subject: [PATCH 246/279] shallow resolve in orphan check --- .../src/coherence/orphan.rs | 1 + .../src/solve/assembly/mod.rs | 12 ++--- .../src/solve/eval_ctxt/mod.rs | 12 +++++ .../src/traits/coherence.rs | 53 +++++++++---------- .../src/traits/select/mod.rs | 2 +- 5 files changed, 44 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index a256d11fd5aa..819e0925f68d 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -330,6 +330,7 @@ fn orphan_check<'tcx>( }; let Ok(result) = traits::orphan_check_trait_ref::( + &infcx, trait_ref, traits::InCrate::Local { mode }, lazily_normalize_ty, diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index b082b0bd4c8a..280975f63bd3 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -2,7 +2,6 @@ use crate::solve::GoalSource; use crate::solve::{inspect, EvalCtxt, SolverMode}; -use crate::traits::coherence; use rustc_hir::def_id::DefId; use rustc_infer::traits::query::NoSolution; use rustc_middle::traits::solve::inspect::ProbeKind; @@ -769,13 +768,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { candidates.extend(self.probe_trait_candidate(CandidateSource::CoherenceUnknowable).enter( |ecx| { let trait_ref = goal.predicate.trait_ref(tcx); - let lazily_normalize_ty = |ty| ecx.structurally_normalize_ty(goal.param_env, ty); - - match coherence::trait_ref_is_knowable(tcx, trait_ref, lazily_normalize_ty)? { - Ok(()) => Err(NoSolution), - Err(_) => { - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) - } + if ecx.trait_ref_is_knowable(goal.param_env, trait_ref)? { + Err(NoSolution) + } else { + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } }, )) diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 8425d68ab59d..1710746ae504 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -27,6 +27,7 @@ use rustc_span::DUMMY_SP; use std::io::Write; use std::ops::ControlFlow; +use crate::traits::coherence; use crate::traits::vtable::{count_own_vtable_entries, prepare_vtable_segments, VtblSegment}; use super::inspect::ProofTreeBuilder; @@ -942,6 +943,17 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } + pub(super) fn trait_ref_is_knowable( + &mut self, + param_env: ty::ParamEnv<'tcx>, + trait_ref: ty::TraitRef<'tcx>, + ) -> Result { + let infcx = self.infcx; + let lazily_normalize_ty = |ty| self.structurally_normalize_ty(param_env, ty); + coherence::trait_ref_is_knowable(infcx, trait_ref, lazily_normalize_ty) + .map(|is_knowable| is_knowable.is_ok()) + } + pub(super) fn can_define_opaque_ty(&self, def_id: impl Into) -> bool { self.infcx.can_define_opaque_ty(def_id) } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 730b7ea70c69..86e7c42376aa 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -618,19 +618,20 @@ fn try_prove_negated_where_clause<'tcx>( /// This both checks whether any downstream or sibling crates could /// implement it and whether an upstream crate can add this impl /// without breaking backwards compatibility. -#[instrument(level = "debug", skip(tcx, lazily_normalize_ty), ret)] +#[instrument(level = "debug", skip(infcx, lazily_normalize_ty), ret)] pub fn trait_ref_is_knowable<'tcx, E: Debug>( - tcx: TyCtxt<'tcx>, + infcx: &InferCtxt<'tcx>, trait_ref: ty::TraitRef<'tcx>, mut lazily_normalize_ty: impl FnMut(Ty<'tcx>) -> Result, E>, ) -> Result, E> { - if orphan_check_trait_ref(trait_ref, InCrate::Remote, &mut lazily_normalize_ty)?.is_ok() { + if orphan_check_trait_ref(infcx, trait_ref, InCrate::Remote, &mut lazily_normalize_ty)?.is_ok() + { // A downstream or cousin crate is allowed to implement some // generic parameters of this trait-ref. return Ok(Err(Conflict::Downstream)); } - if trait_ref_is_local_or_fundamental(tcx, trait_ref) { + if trait_ref_is_local_or_fundamental(infcx.tcx, trait_ref) { // This is a local or fundamental trait, so future-compatibility // is no concern. We know that downstream/cousin crates are not // allowed to implement a generic parameter of this trait ref, @@ -648,6 +649,7 @@ pub fn trait_ref_is_knowable<'tcx, E: Debug>( // about future-compatibility, which means that we're OK if // we are an owner. if orphan_check_trait_ref( + infcx, trait_ref, InCrate::Local { mode: OrphanCheckMode::Proper }, &mut lazily_normalize_ty, @@ -786,38 +788,32 @@ pub struct UncoveredTyParams<'tcx, T> { /// /// Note that this function is never called for types that have both type /// parameters and inference variables. -#[instrument(level = "trace", skip(lazily_normalize_ty), ret)] +#[instrument(level = "trace", skip(infcx, lazily_normalize_ty), ret)] pub fn orphan_check_trait_ref<'tcx, E: Debug>( + infcx: &InferCtxt<'tcx>, trait_ref: ty::TraitRef<'tcx>, in_crate: InCrate, lazily_normalize_ty: impl FnMut(Ty<'tcx>) -> Result, E>, ) -> Result>>, E> { - if trait_ref.has_infer() && trait_ref.has_param() { - bug!( - "can't orphan check a trait ref with both params and inference variables {:?}", - trait_ref - ); + if trait_ref.has_param() { + bug!("orphan check only expects inference variables: {trait_ref:?}"); } - let mut checker = OrphanChecker::new(in_crate, lazily_normalize_ty); - - // Does there exist some local type after the `ParamTy`. - let search_first_local_ty = |checker: &mut OrphanChecker<'tcx, _>| { - checker.search_first_local_ty = true; - match trait_ref.visit_with(checker).break_value() { - Some(OrphanCheckEarlyExit::LocalTy(local_ty)) => Some(local_ty), - _ => None, - } - }; - + let mut checker = OrphanChecker::new(infcx, in_crate, lazily_normalize_ty); Ok(match trait_ref.visit_with(&mut checker) { ControlFlow::Continue(()) => Err(OrphanCheckErr::NonLocalInputType(checker.non_local_tys)), ControlFlow::Break(residual) => match residual { OrphanCheckEarlyExit::NormalizationFailure(err) => return Err(err), OrphanCheckEarlyExit::UncoveredTyParam(ty) => { + // Does there exist some local type after the `ParamTy`. + checker.search_first_local_ty = true; + let local_ty = match trait_ref.visit_with(&mut checker).break_value() { + Some(OrphanCheckEarlyExit::LocalTy(local_ty)) => Some(local_ty), + _ => None, + }; Err(OrphanCheckErr::UncoveredTyParams(UncoveredTyParams { uncovered: ty, - local_ty: search_first_local_ty(&mut checker), + local_ty, })) } OrphanCheckEarlyExit::LocalTy(_) => Ok(()), @@ -825,7 +821,8 @@ pub fn orphan_check_trait_ref<'tcx, E: Debug>( }) } -struct OrphanChecker<'tcx, F> { +struct OrphanChecker<'a, 'tcx, F> { + infcx: &'a InferCtxt<'tcx>, in_crate: InCrate, in_self_ty: bool, lazily_normalize_ty: F, @@ -834,12 +831,13 @@ struct OrphanChecker<'tcx, F> { non_local_tys: Vec<(Ty<'tcx>, IsFirstInputType)>, } -impl<'tcx, F, E> OrphanChecker<'tcx, F> +impl<'a, 'tcx, F, E> OrphanChecker<'a, 'tcx, F> where F: FnOnce(Ty<'tcx>) -> Result, E>, { - fn new(in_crate: InCrate, lazily_normalize_ty: F) -> Self { + fn new(infcx: &'a InferCtxt<'tcx>, in_crate: InCrate, lazily_normalize_ty: F) -> Self { OrphanChecker { + infcx, in_crate, in_self_ty: true, lazily_normalize_ty, @@ -878,7 +876,7 @@ enum OrphanCheckEarlyExit<'tcx, E> { LocalTy(Ty<'tcx>), } -impl<'tcx, F, E> TypeVisitor> for OrphanChecker<'tcx, F> +impl<'a, 'tcx, F, E> TypeVisitor> for OrphanChecker<'a, 'tcx, F> where F: FnMut(Ty<'tcx>) -> Result, E>, { @@ -889,6 +887,7 @@ where } fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { + let ty = self.infcx.shallow_resolve(ty); let ty = match (self.lazily_normalize_ty)(ty) { Ok(norm_ty) if norm_ty.is_ty_var() => ty, Ok(norm_ty) => norm_ty, @@ -1149,7 +1148,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> { }; infcx.probe(|_| { - match trait_ref_is_knowable(infcx.tcx, trait_ref, lazily_normalize_ty) { + match trait_ref_is_knowable(infcx, trait_ref, lazily_normalize_ty) { Err(()) => {} Ok(Ok(())) => warn!("expected an unknowable trait ref: {trait_ref:?}"), Ok(Err(conflict)) => { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 35ab333c9b31..18cb3184fe11 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1497,7 +1497,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // bound regions. let trait_ref = predicate.skip_binder().trait_ref; - coherence::trait_ref_is_knowable::(self.tcx(), trait_ref, |ty| Ok(ty)).unwrap() + coherence::trait_ref_is_knowable::(self.infcx, trait_ref, |ty| Ok(ty)).unwrap() } /// Returns `true` if the global caches can be used. From 698d7a031eb65a9d47952f7ba3b13aa16fcbb11b Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 2 May 2024 17:49:23 +0200 Subject: [PATCH 247/279] Inline & delete `Ty::new_unit`, since it's just a field access --- .../rustc_codegen_gcc/src/intrinsic/mod.rs | 4 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 4 +- .../rustc_hir_analysis/src/check/intrinsic.rs | 44 +++++++++---------- .../src/hir_ty_lowering/mod.rs | 2 +- compiler/rustc_hir_typeck/src/_match.rs | 2 +- compiler/rustc_hir_typeck/src/coercion.rs | 2 +- compiler/rustc_hir_typeck/src/expr.rs | 10 ++--- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 6 +-- compiler/rustc_hir_typeck/src/op.rs | 2 +- compiler/rustc_lint/src/unit_bindings.rs | 5 +-- compiler/rustc_middle/src/ty/layout.rs | 4 +- compiler/rustc_middle/src/ty/sty.rs | 5 --- compiler/rustc_mir_build/src/build/mod.rs | 2 +- compiler/rustc_mir_build/src/thir/cx/mod.rs | 4 +- .../rustc_mir_dataflow/src/elaborate_drops.rs | 2 +- compiler/rustc_mir_transform/src/coroutine.rs | 2 +- .../error_reporting/type_err_ctxt_ext.rs | 2 +- .../src/traits/object_safety.rs | 2 +- compiler/rustc_ty_utils/src/abi.rs | 2 +- 19 files changed, 50 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index b7aec97ad8c2..451e5258ebd1 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -1223,7 +1223,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>( tcx, ty::Binder::dummy(tcx.mk_fn_sig( iter::once(i8p), - Ty::new_unit(tcx), + tcx.types.unit, false, rustc_hir::Unsafety::Unsafe, Abi::Rust, @@ -1234,7 +1234,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>( tcx, ty::Binder::dummy(tcx.mk_fn_sig( [i8p, i8p].iter().cloned(), - Ty::new_unit(tcx), + tcx.types.unit, false, rustc_hir::Unsafety::Unsafe, Abi::Rust, diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 41347333ea6f..56550dbfa4b8 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -984,7 +984,7 @@ fn get_rust_try_fn<'ll, 'tcx>( tcx, ty::Binder::dummy(tcx.mk_fn_sig( [i8p], - Ty::new_unit(tcx), + tcx.types.unit, false, hir::Unsafety::Unsafe, Abi::Rust, @@ -995,7 +995,7 @@ fn get_rust_try_fn<'ll, 'tcx>( tcx, ty::Binder::dummy(tcx.mk_fn_sig( [i8p, i8p], - Ty::new_unit(tcx), + tcx.types.unit, false, hir::Unsafety::Unsafe, Abi::Rust, diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 74324c8695b8..eb1fa1baecca 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -208,11 +208,11 @@ pub fn check_intrinsic_type( Ty::new_tup(tcx, &[param(0), tcx.types.bool]), ), "load" => (1, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)), - "store" => (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx)), + "store" => (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit), "xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" | "min" | "umax" | "umin" => (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], param(0)), - "fence" | "singlethreadfence" => (0, Vec::new(), Ty::new_unit(tcx)), + "fence" | "singlethreadfence" => (0, Vec::new(), tcx.types.unit), op => { tcx.dcx().emit_err(UnrecognizedAtomicOperation { span, op }); return; @@ -224,7 +224,7 @@ pub fn check_intrinsic_type( let (n_tps, n_cts, inputs, output) = match intrinsic_name { sym::abort => (0, 0, vec![], tcx.types.never), sym::unreachable => (0, 0, vec![], tcx.types.never), - sym::breakpoint => (0, 0, vec![], Ty::new_unit(tcx)), + sym::breakpoint => (0, 0, vec![], tcx.types.unit), sym::size_of | sym::pref_align_of | sym::min_align_of | sym::variant_count => { (1, 0, vec![], tcx.types.usize) } @@ -235,14 +235,14 @@ pub fn check_intrinsic_type( sym::caller_location => (0, 0, vec![], tcx.caller_location_ty()), sym::assert_inhabited | sym::assert_zero_valid - | sym::assert_mem_uninitialized_valid => (1, 0, vec![], Ty::new_unit(tcx)), - sym::forget => (1, 0, vec![param(0)], Ty::new_unit(tcx)), + | sym::assert_mem_uninitialized_valid => (1, 0, vec![], tcx.types.unit), + sym::forget => (1, 0, vec![param(0)], tcx.types.unit), sym::transmute | sym::transmute_unchecked => (2, 0, vec![param(0)], param(1)), sym::prefetch_read_data | sym::prefetch_write_data | sym::prefetch_read_instruction | sym::prefetch_write_instruction => { - (1, 0, vec![Ty::new_imm_ptr(tcx, param(0)), tcx.types.i32], Ty::new_unit(tcx)) + (1, 0, vec![Ty::new_imm_ptr(tcx, param(0)), tcx.types.i32], tcx.types.unit) } sym::needs_drop => (1, 0, vec![], tcx.types.bool), @@ -270,7 +270,7 @@ pub fn check_intrinsic_type( Ty::new_mut_ptr(tcx, param(0)), tcx.types.usize, ], - Ty::new_unit(tcx), + tcx.types.unit, ), sym::volatile_copy_memory | sym::volatile_copy_nonoverlapping_memory => ( 1, @@ -280,7 +280,7 @@ pub fn check_intrinsic_type( Ty::new_imm_ptr(tcx, param(0)), tcx.types.usize, ], - Ty::new_unit(tcx), + tcx.types.unit, ), sym::compare_bytes => { let byte_ptr = Ty::new_imm_ptr(tcx, tcx.types.u8); @@ -290,7 +290,7 @@ pub fn check_intrinsic_type( 1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), tcx.types.u8, tcx.types.usize], - Ty::new_unit(tcx), + tcx.types.unit, ), sym::sqrtf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), @@ -409,7 +409,7 @@ pub fn check_intrinsic_type( (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)) } sym::volatile_store | sym::unaligned_volatile_store => { - (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx)) + (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit) } sym::ctpop | sym::ctlz | sym::ctlz_nonzero | sym::cttz | sym::cttz_nonzero => { @@ -440,7 +440,7 @@ pub fn check_intrinsic_type( 0, 1, vec![Ty::new_mut_ptr(tcx, tcx.types.u8), tcx.types.usize, tcx.types.usize], - Ty::new_unit(tcx), + tcx.types.unit, ), sym::ptr_offset_from => ( @@ -477,16 +477,16 @@ pub fn check_intrinsic_type( | sym::frem_algebraic => (1, 0, vec![param(0), param(0)], param(0)), sym::float_to_int_unchecked => (2, 0, vec![param(0)], param(1)), - sym::assume => (0, 1, vec![tcx.types.bool], Ty::new_unit(tcx)), + sym::assume => (0, 1, vec![tcx.types.bool], tcx.types.unit), sym::likely => (0, 1, vec![tcx.types.bool], tcx.types.bool), sym::unlikely => (0, 1, vec![tcx.types.bool], tcx.types.bool), sym::read_via_copy => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)), sym::write_via_move => { - (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx)) + (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit) } - sym::typed_swap => (1, 1, vec![Ty::new_mut_ptr(tcx, param(0)); 2], Ty::new_unit(tcx)), + sym::typed_swap => (1, 1, vec![Ty::new_mut_ptr(tcx, param(0)); 2], tcx.types.unit), sym::discriminant_value => { let assoc_items = tcx.associated_item_def_ids( @@ -511,14 +511,14 @@ pub fn check_intrinsic_type( let mut_u8 = Ty::new_mut_ptr(tcx, tcx.types.u8); let try_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig( [mut_u8], - Ty::new_unit(tcx), + tcx.types.unit, false, hir::Unsafety::Normal, Abi::Rust, )); let catch_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig( [mut_u8, mut_u8], - Ty::new_unit(tcx), + tcx.types.unit, false, hir::Unsafety::Normal, Abi::Rust, @@ -532,14 +532,14 @@ pub fn check_intrinsic_type( } sym::va_start | sym::va_end => match mk_va_list_ty(hir::Mutability::Mut) { - Some((va_list_ref_ty, _)) => (0, 0, vec![va_list_ref_ty], Ty::new_unit(tcx)), + Some((va_list_ref_ty, _)) => (0, 0, vec![va_list_ref_ty], tcx.types.unit), None => bug!("`va_list` lang item needed for C-variadic intrinsics"), }, sym::va_copy => match mk_va_list_ty(hir::Mutability::Not) { Some((va_list_ref_ty, va_list_ty)) => { let va_list_ptr_ty = Ty::new_mut_ptr(tcx, va_list_ty); - (0, 0, vec![va_list_ptr_ty, va_list_ref_ty], Ty::new_unit(tcx)) + (0, 0, vec![va_list_ptr_ty, va_list_ref_ty], tcx.types.unit) } None => bug!("`va_list` lang item needed for C-variadic intrinsics"), }, @@ -550,7 +550,7 @@ pub fn check_intrinsic_type( }, sym::nontemporal_store => { - (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx)) + (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit) } sym::raw_eq => { @@ -570,7 +570,7 @@ pub fn check_intrinsic_type( sym::const_eval_select => (4, 1, vec![param(0), param(1), param(2)], param(3)), sym::vtable_size | sym::vtable_align => { - (0, 0, vec![Ty::new_imm_ptr(tcx, Ty::new_unit(tcx))], tcx.types.usize) + (0, 0, vec![Ty::new_imm_ptr(tcx, tcx.types.unit)], tcx.types.usize) } // This type check is not particularly useful, but the `where` bounds @@ -623,8 +623,8 @@ pub fn check_intrinsic_type( sym::simd_fma => (1, 0, vec![param(0), param(0), param(0)], param(0)), sym::simd_gather => (3, 0, vec![param(0), param(1), param(2)], param(0)), sym::simd_masked_load => (3, 0, vec![param(0), param(1), param(2)], param(2)), - sym::simd_masked_store => (3, 0, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)), - sym::simd_scatter => (3, 0, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)), + sym::simd_masked_store => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit), + sym::simd_scatter => (3, 0, vec![param(0), param(1), param(2)], tcx.types.unit), sym::simd_insert => (2, 0, vec![param(0), tcx.types.u32, param(1)], param(0)), sym::simd_extract => (2, 0, vec![param(0), tcx.types.u32], param(1)), sym::simd_cast diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 63da27246a2a..f7213442ac2d 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2370,7 +2370,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.lower_ty(output) } } - hir::FnRetTy::DefaultReturn(..) => Ty::new_unit(tcx), + hir::FnRetTy::DefaultReturn(..) => tcx.types.unit, }; debug!(?output_ty); diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 334a424d2e26..4ff6678fc914 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -66,7 +66,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // us to give better error messages (pointing to a usually better // arm for inconsistent arms or to the whole match when a `()` type // is required). - Expectation::ExpectHasType(ety) if ety != Ty::new_unit(self.tcx) => ety, + Expectation::ExpectHasType(ety) if ety != tcx.types.unit => ety, _ => self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr.span }), }; CoerceMany::with_coercion_sites(coerce_first, arms) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 4165fa7f07d1..825276aef421 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1462,7 +1462,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { fcx, cause, None, - Ty::new_unit(fcx.tcx), + fcx.tcx.types.unit, augment_error, label_unit_as_expected, ) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 15792287a872..8b1ea7c952cb 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -654,7 +654,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { // Otherwise, this is a break *without* a value. That's // always legal, and is equivalent to `break ()`. - e_ty = Ty::new_unit(tcx); + e_ty = tcx.types.unit; cause = self.misc(expr.span); } @@ -1133,7 +1133,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // The expected type is `bool` but this will result in `()` so we can reasonably // say that the user intended to write `lhs == rhs` instead of `lhs = rhs`. // The likely cause of this is `if foo = bar { .. }`. - let actual_ty = Ty::new_unit(self.tcx); + let actual_ty = self.tcx.types.unit; let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap(); let lhs_ty = self.check_expr(lhs); let rhs_ty = self.check_expr(rhs); @@ -1256,7 +1256,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Err(guar) = (lhs_ty, rhs_ty).error_reported() { Ty::new_error(self.tcx, guar) } else { - Ty::new_unit(self.tcx) + self.tcx.types.unit } } @@ -1319,7 +1319,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if ctxt.coerce.is_none() && !ctxt.may_break { self.dcx().span_bug(body.span, "no coercion, but loop may not break"); } - ctxt.coerce.map(|c| c.complete(self)).unwrap_or_else(|| Ty::new_unit(self.tcx)) + ctxt.coerce.map(|c| c.complete(self)).unwrap_or_else(|| self.tcx.types.unit) } /// Checks a method call. @@ -3174,7 +3174,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.dcx().emit_err(YieldExprOutsideOfCoroutine { span: expr.span }); // Avoid expressions without types during writeback (#78653). self.check_expr(value); - Ty::new_unit(self.tcx) + self.tcx.types.unit } } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index b729fbe844a3..e45e0884affb 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1660,7 +1660,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::StmtKind::Item(_) => {} hir::StmtKind::Expr(ref expr) => { // Check with expected type of `()`. - self.check_expr_has_type_or_error(expr, Ty::new_unit(self.tcx), |err| { + self.check_expr_has_type_or_error(expr, self.tcx.types.unit, |err| { if expr.can_have_side_effects() { self.suggest_semicolon_at_end(expr.span, err); } @@ -1676,7 +1676,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) { - let unit = Ty::new_unit(self.tcx); + let unit = self.tcx.types.unit; let ty = self.check_block_with_expected(blk, ExpectHasType(unit)); // if the block produces a `!` value, that can always be @@ -1794,7 +1794,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { blk.span, blk.hir_id, expected_ty, - Ty::new_unit(self.tcx), + self.tcx.types.unit, ); } if !self.err_ctxt().consider_removing_semicolon( diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 49d0c8bfcd1b..a4f840d849dd 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -39,7 +39,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = if !lhs_ty.is_ty_var() && !rhs_ty.is_ty_var() && is_builtin_binop(lhs_ty, rhs_ty, op) { self.enforce_builtin_binop_types(lhs.span, lhs_ty, rhs.span, rhs_ty, op); - Ty::new_unit(self.tcx) + self.tcx.types.unit } else { return_ty }; diff --git a/compiler/rustc_lint/src/unit_bindings.rs b/compiler/rustc_lint/src/unit_bindings.rs index 137e0dcb330a..8202bfa805a2 100644 --- a/compiler/rustc_lint/src/unit_bindings.rs +++ b/compiler/rustc_lint/src/unit_bindings.rs @@ -1,7 +1,6 @@ use crate::lints::UnitBindingsDiag; use crate::{LateLintPass, LintContext}; use rustc_hir as hir; -use rustc_middle::ty::Ty; use rustc_session::{declare_lint, declare_lint_pass}; declare_lint! { @@ -57,8 +56,8 @@ impl<'tcx> LateLintPass<'tcx> for UnitBindings { && let Some(init) = local.init && let init_ty = tyck_results.expr_ty(init) && let local_ty = tyck_results.node_type(local.hir_id) - && init_ty == Ty::new_unit(cx.tcx) - && local_ty == Ty::new_unit(cx.tcx) + && init_ty == cx.tcx.types.unit + && local_ty == cx.tcx.types.unit && local.ty.is_none() && !matches!(init.kind, hir::ExprKind::Tup([])) && !matches!(local.pat.kind, hir::PatKind::Tuple([], ..)) diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 189b95becfb5..f8490e5e15fc 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -125,7 +125,7 @@ impl Primitive { F64 => tcx.types.f64, F128 => tcx.types.f128, // FIXME(erikdesjardins): handle non-default addrspace ptr sizes - Pointer(_) => Ty::new_mut_ptr(tcx, Ty::new_unit(tcx)), + Pointer(_) => Ty::new_mut_ptr(tcx, tcx.types.unit), } } @@ -775,7 +775,7 @@ where // (which may have no non-DST form), and will work as long // as the `Abi` or `FieldsShape` is checked by users. if i == 0 { - let nil = Ty::new_unit(tcx); + let nil = tcx.types.unit; let unit_ptr_ty = if this.ty.is_unsafe_ptr() { Ty::new_mut_ptr(tcx, nil) } else { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index d9350f36d33d..de70c4f7b65a 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1750,11 +1750,6 @@ impl<'tcx> Ty<'tcx> { // misc - #[inline] - pub fn new_unit(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { - tcx.types.unit - } - #[inline] pub fn new_static_str(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, tcx.types.str_) diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 3c18afe1a78e..d6e6cc957b4b 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -997,7 +997,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match self.unit_temp { Some(tmp) => tmp, None => { - let ty = Ty::new_unit(self.tcx); + let ty = self.tcx.types.unit; let fn_span = self.fn_span; let tmp = self.temp(ty, fn_span); self.unit_temp = Some(tmp); diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index f4f591d15b93..79738b540354 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -15,7 +15,7 @@ use rustc_hir::HirId; use rustc_hir::Node; use rustc_middle::middle::region; use rustc_middle::thir::*; -use rustc_middle::ty::{self, RvalueScopes, Ty, TyCtxt}; +use rustc_middle::ty::{self, RvalueScopes, TyCtxt}; pub(crate) fn thir_body( tcx: TyCtxt<'_>, @@ -39,7 +39,7 @@ pub(crate) fn thir_body( // It will always be `()` in this case. if tcx.is_coroutine(owner_def.to_def_id()) && body.params.is_empty() { cx.thir.params.push(Param { - ty: Ty::new_unit(tcx), + ty: tcx.types.unit, pat: None, ty_span: None, self_kind: None, diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index bfc01dc4da4b..185e87baed8c 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -631,7 +631,7 @@ where let ref_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, ty); let ref_place = self.new_temp(ref_ty); - let unit_temp = Place::from(self.new_temp(Ty::new_unit(tcx))); + let unit_temp = Place::from(self.new_temp(tcx.types.unit)); let result = BasicBlockData { statements: vec![self.assign( diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index b745d97567d6..3008016863e4 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1260,7 +1260,7 @@ fn create_coroutine_drop_shim<'tcx>( } // Replace the return variable - body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(Ty::new_unit(tcx), source_info); + body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(tcx.types.unit, source_info); make_coroutine_state_argument_indirect(tcx, &mut body); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 7e30fb608972..e50cb2af4b85 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -781,7 +781,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { && self.fallback_has_occurred { let predicate = trait_predicate.map_bound(|trait_pred| { - trait_pred.with_self_ty(self.tcx, Ty::new_unit(self.tcx)) + trait_pred.with_self_ty(self.tcx, tcx.types.unit) }); let unit_obligation = obligation.with(tcx, predicate); if self.predicate_may_hold(&unit_obligation) { diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 5e1343b50ce7..0e15dd275371 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -519,7 +519,7 @@ fn virtual_call_violations_for_method<'tcx>( // e.g., `Rc<()>` let unit_receiver_ty = - receiver_for_self_ty(tcx, receiver_ty, Ty::new_unit(tcx), method.def_id); + receiver_for_self_ty(tcx, receiver_ty, tcx.types.unit, method.def_id); match abi_of_ty(unit_receiver_ty) { Some(Abi::Scalar(..)) => (), diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index f0cea1f0baf3..c6b836285066 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -854,7 +854,7 @@ fn make_thin_self_ptr<'tcx>( // we now have a type like `*mut RcBox` // change its layout to that of `*mut ()`, a thin pointer, but keep the same type // this is understood as a special case elsewhere in the compiler - let unit_ptr_ty = Ty::new_mut_ptr(tcx, Ty::new_unit(tcx)); + let unit_ptr_ty = Ty::new_mut_ptr(tcx, tcx.types.unit); TyAndLayout { ty: fat_pointer_ty, From 1c9a61d2111c93407018c99e15ddd78ea18a234e Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 2 May 2024 17:50:51 +0200 Subject: [PATCH 248/279] Don't use `Ty::new_unit` in miri --- src/tools/miri/src/machine.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 8b2868717748..4dacb6db8da9 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -380,7 +380,7 @@ impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> { let mut_raw_ptr = Ty::new_mut_ptr(tcx, tcx.types.unit); let const_raw_ptr = Ty::new_imm_ptr(tcx, tcx.types.unit); Ok(Self { - unit: layout_cx.layout_of(Ty::new_unit(tcx))?, + unit: layout_cx.layout_of(tcx.types.unit)?, i8: layout_cx.layout_of(tcx.types.i8)?, i16: layout_cx.layout_of(tcx.types.i16)?, i32: layout_cx.layout_of(tcx.types.i32)?, From 09aa77299b473533335f7d49f43f096645253ea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Thu, 2 May 2024 17:57:23 +0200 Subject: [PATCH 249/279] Cleanup: Rid the `rmake` test runners of `extern crate run_make_support;` --- tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs | 2 -- tests/run-make/a-b-a-linker-guard/rmake.rs | 2 -- tests/run-make/arguments-non-c-like-enum/rmake.rs | 2 -- tests/run-make/artifact-incr-cache-no-obj/rmake.rs | 2 -- tests/run-make/artifact-incr-cache/rmake.rs | 2 -- tests/run-make/compiler-builtins/rmake.rs | 2 -- tests/run-make/core-no-fp-fmt-parse/rmake.rs | 2 -- tests/run-make/cross-lang-lto-riscv-abi/rmake.rs | 1 - tests/run-make/exit-code/rmake.rs | 2 -- tests/run-make/issue-107495-archive-permissions/rmake.rs | 1 - tests/run-make/no-input-file/rmake.rs | 2 -- tests/run-make/non-unicode-env/rmake.rs | 2 -- tests/run-make/non-unicode-in-incremental-dir/rmake.rs | 2 -- tests/run-make/print-cfg/rmake.rs | 2 -- tests/run-make/print-native-static-libs/rmake.rs | 2 -- tests/run-make/print-to-output/rmake.rs | 2 -- tests/run-make/repr128-dwarf/rmake.rs | 2 -- tests/run-make/rust-lld-custom-target/rmake.rs | 2 -- tests/run-make/rust-lld/rmake.rs | 2 -- tests/run-make/rustdoc-test-args/rmake.rs | 2 -- tests/run-make/wasm-abi/rmake.rs | 2 -- tests/run-make/wasm-custom-section/rmake.rs | 1 - tests/run-make/wasm-custom-sections-opt/rmake.rs | 1 - tests/run-make/wasm-export-all-symbols/rmake.rs | 2 -- tests/run-make/wasm-import-module/rmake.rs | 2 -- tests/run-make/wasm-panic-small/rmake.rs | 2 -- tests/run-make/wasm-spurious-import/rmake.rs | 2 -- tests/run-make/wasm-stringify-ints-small/rmake.rs | 2 -- tests/run-make/wasm-symbols-different-module/rmake.rs | 1 - tests/run-make/wasm-symbols-not-exported/rmake.rs | 1 - tests/run-make/wasm-symbols-not-imported/rmake.rs | 1 - 31 files changed, 55 deletions(-) diff --git a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs index 1204260a2f46..fe0ceaf6b043 100644 --- a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs +++ b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs @@ -3,8 +3,6 @@ // Check that the `CURRENT_RUSTC_VERSION` placeholder is correctly replaced by the current // `rustc` version and the `since` property in feature stability gating is properly respected. -extern crate run_make_support; - use std::path::PathBuf; use run_make_support::{rustc, aux_build}; diff --git a/tests/run-make/a-b-a-linker-guard/rmake.rs b/tests/run-make/a-b-a-linker-guard/rmake.rs index ffc1b2000b90..ee6d655bc760 100644 --- a/tests/run-make/a-b-a-linker-guard/rmake.rs +++ b/tests/run-make/a-b-a-linker-guard/rmake.rs @@ -3,8 +3,6 @@ // Test that if we build `b` against a version of `a` that has one set of types, it will not run // with a dylib that has a different set of types. -extern crate run_make_support; - use run_make_support::{run, run_fail, rustc}; fn main() { diff --git a/tests/run-make/arguments-non-c-like-enum/rmake.rs b/tests/run-make/arguments-non-c-like-enum/rmake.rs index 624a7fb22518..13230206ca87 100644 --- a/tests/run-make/arguments-non-c-like-enum/rmake.rs +++ b/tests/run-make/arguments-non-c-like-enum/rmake.rs @@ -1,8 +1,6 @@ //! Check that non-trivial `repr(C)` enum in Rust has valid C layout. //@ ignore-cross-compile -extern crate run_make_support; - use run_make_support::{cc, extra_c_flags, extra_cxx_flags, run, rustc, static_lib}; pub fn main() { diff --git a/tests/run-make/artifact-incr-cache-no-obj/rmake.rs b/tests/run-make/artifact-incr-cache-no-obj/rmake.rs index de55de2a1ee2..6613698ae1df 100644 --- a/tests/run-make/artifact-incr-cache-no-obj/rmake.rs +++ b/tests/run-make/artifact-incr-cache-no-obj/rmake.rs @@ -5,8 +5,6 @@ // // Fixes: rust-lang/rust#123234 -extern crate run_make_support; - use run_make_support::{rustc, tmp_dir}; fn main() { diff --git a/tests/run-make/artifact-incr-cache/rmake.rs b/tests/run-make/artifact-incr-cache/rmake.rs index bb6513680818..106f363eb8da 100644 --- a/tests/run-make/artifact-incr-cache/rmake.rs +++ b/tests/run-make/artifact-incr-cache/rmake.rs @@ -7,8 +7,6 @@ // Also see discussion at // -extern crate run_make_support; - use run_make_support::{rustc, tmp_dir}; fn main() { diff --git a/tests/run-make/compiler-builtins/rmake.rs b/tests/run-make/compiler-builtins/rmake.rs index 97ff12877f10..178478484599 100644 --- a/tests/run-make/compiler-builtins/rmake.rs +++ b/tests/run-make/compiler-builtins/rmake.rs @@ -14,8 +14,6 @@ #![deny(warnings)] -extern crate run_make_support; - use run_make_support::object; use run_make_support::object::read::archive::ArchiveFile; use run_make_support::object::read::Object; diff --git a/tests/run-make/core-no-fp-fmt-parse/rmake.rs b/tests/run-make/core-no-fp-fmt-parse/rmake.rs index 2748d4359c36..e3484888ca5a 100644 --- a/tests/run-make/core-no-fp-fmt-parse/rmake.rs +++ b/tests/run-make/core-no-fp-fmt-parse/rmake.rs @@ -1,8 +1,6 @@ // This test checks that the core library of Rust can be compiled without enabling // support for formatting and parsing floating-point numbers. -extern crate run_make_support; - use run_make_support::rustc; use std::path::PathBuf; diff --git a/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs b/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs index b534a99f8cfe..61f32762d8b7 100644 --- a/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs +++ b/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs @@ -2,7 +2,6 @@ //! which requires extra `target-abi` metadata to be emitted. //@ needs-matching-clang //@ needs-llvm-components riscv -extern crate run_make_support; use run_make_support::{bin_name, clang, llvm_readobj, rustc, tmp_dir}; use std::{ diff --git a/tests/run-make/exit-code/rmake.rs b/tests/run-make/exit-code/rmake.rs index f387626287e3..f4ceabe126cb 100644 --- a/tests/run-make/exit-code/rmake.rs +++ b/tests/run-make/exit-code/rmake.rs @@ -1,7 +1,5 @@ // Test that we exit with the correct exit code for successful / unsuccessful / ICE compilations -extern crate run_make_support; - use run_make_support::{rustc, rustdoc, tmp_dir}; fn main() { diff --git a/tests/run-make/issue-107495-archive-permissions/rmake.rs b/tests/run-make/issue-107495-archive-permissions/rmake.rs index 40deabe15b73..db25e9b033c1 100644 --- a/tests/run-make/issue-107495-archive-permissions/rmake.rs +++ b/tests/run-make/issue-107495-archive-permissions/rmake.rs @@ -2,7 +2,6 @@ #[cfg(unix)] extern crate libc; -extern crate run_make_support; use run_make_support::{aux_build, tmp_dir}; use std::fs; diff --git a/tests/run-make/no-input-file/rmake.rs b/tests/run-make/no-input-file/rmake.rs index 26df7e80dfbf..15e582311f09 100644 --- a/tests/run-make/no-input-file/rmake.rs +++ b/tests/run-make/no-input-file/rmake.rs @@ -1,5 +1,3 @@ -extern crate run_make_support; - use run_make_support::{diff, rustc}; fn main() { diff --git a/tests/run-make/non-unicode-env/rmake.rs b/tests/run-make/non-unicode-env/rmake.rs index ba4aa1609b56..a4843a52efd5 100644 --- a/tests/run-make/non-unicode-env/rmake.rs +++ b/tests/run-make/non-unicode-env/rmake.rs @@ -1,5 +1,3 @@ -extern crate run_make_support; - use run_make_support::rustc; fn main() { diff --git a/tests/run-make/non-unicode-in-incremental-dir/rmake.rs b/tests/run-make/non-unicode-in-incremental-dir/rmake.rs index 129e424f27a4..40152e0411d3 100644 --- a/tests/run-make/non-unicode-in-incremental-dir/rmake.rs +++ b/tests/run-make/non-unicode-in-incremental-dir/rmake.rs @@ -1,5 +1,3 @@ -extern crate run_make_support; - use run_make_support::{rustc, tmp_dir}; fn main() { diff --git a/tests/run-make/print-cfg/rmake.rs b/tests/run-make/print-cfg/rmake.rs index 71db7b8a6937..6e72c16f1f9a 100644 --- a/tests/run-make/print-cfg/rmake.rs +++ b/tests/run-make/print-cfg/rmake.rs @@ -5,8 +5,6 @@ //! //! It also checks that some targets have the correct set cfgs. -extern crate run_make_support; - use std::collections::HashSet; use std::ffi::OsString; use std::io::BufRead; diff --git a/tests/run-make/print-native-static-libs/rmake.rs b/tests/run-make/print-native-static-libs/rmake.rs index fc8701777d12..5249920cc60e 100644 --- a/tests/run-make/print-native-static-libs/rmake.rs +++ b/tests/run-make/print-native-static-libs/rmake.rs @@ -12,8 +12,6 @@ //@ ignore-cross-compile //@ ignore-wasm -extern crate run_make_support; - use std::io::BufRead; use run_make_support::{rustc, is_msvc}; diff --git a/tests/run-make/print-to-output/rmake.rs b/tests/run-make/print-to-output/rmake.rs index 8595a0c490b3..f710d0dc3c9b 100644 --- a/tests/run-make/print-to-output/rmake.rs +++ b/tests/run-make/print-to-output/rmake.rs @@ -1,8 +1,6 @@ //! This checks the output of some `--print` options when //! output to a file (instead of stdout) -extern crate run_make_support; - use std::ffi::OsString; use run_make_support::{rustc, target, tmp_dir}; diff --git a/tests/run-make/repr128-dwarf/rmake.rs b/tests/run-make/repr128-dwarf/rmake.rs index f6375344f8f2..d734b2add79a 100644 --- a/tests/run-make/repr128-dwarf/rmake.rs +++ b/tests/run-make/repr128-dwarf/rmake.rs @@ -1,8 +1,6 @@ //@ ignore-windows // This test should be replaced with one in tests/debuginfo once GDB or LLDB support 128-bit enums. -extern crate run_make_support; - use gimli::{AttributeValue, Dwarf, EndianRcSlice, Reader, RunTimeEndian}; use object::{Object, ObjectSection}; use run_make_support::{gimli, object, rustc, tmp_dir}; diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs index b5341725e36e..9bdb69f47d8e 100644 --- a/tests/run-make/rust-lld-custom-target/rmake.rs +++ b/tests/run-make/rust-lld-custom-target/rmake.rs @@ -8,8 +8,6 @@ //@ needs-rust-lld //@ only-x86_64-unknown-linux-gnu -extern crate run_make_support; - use run_make_support::regex::Regex; use run_make_support::rustc; use std::process::Output; diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs index acb6d74aaa8b..feeb82e709e1 100644 --- a/tests/run-make/rust-lld/rmake.rs +++ b/tests/run-make/rust-lld/rmake.rs @@ -5,8 +5,6 @@ //@ ignore-msvc //@ ignore-s390x lld does not yet support s390x as target -extern crate run_make_support; - use run_make_support::regex::Regex; use run_make_support::rustc; use std::process::Output; diff --git a/tests/run-make/rustdoc-test-args/rmake.rs b/tests/run-make/rustdoc-test-args/rmake.rs index c8edfb6370e5..66f3f7cf131c 100644 --- a/tests/run-make/rustdoc-test-args/rmake.rs +++ b/tests/run-make/rustdoc-test-args/rmake.rs @@ -1,5 +1,3 @@ -extern crate run_make_support; - use run_make_support::{rustdoc, tmp_dir}; use std::path::Path; use std::{fs, iter}; diff --git a/tests/run-make/wasm-abi/rmake.rs b/tests/run-make/wasm-abi/rmake.rs index d83332f6e034..a2dcafbbe0f1 100644 --- a/tests/run-make/wasm-abi/rmake.rs +++ b/tests/run-make/wasm-abi/rmake.rs @@ -1,8 +1,6 @@ //@ only-wasm32-wasip1 //@ needs-wasmtime -extern crate run_make_support; - use run_make_support::{rustc, tmp_dir}; use std::path::Path; use std::process::Command; diff --git a/tests/run-make/wasm-custom-section/rmake.rs b/tests/run-make/wasm-custom-section/rmake.rs index 825fcf71514c..0303ca05ca63 100644 --- a/tests/run-make/wasm-custom-section/rmake.rs +++ b/tests/run-make/wasm-custom-section/rmake.rs @@ -1,5 +1,4 @@ //@ only-wasm32-wasip1 -extern crate run_make_support; use run_make_support::{rustc, tmp_dir, wasmparser}; use std::collections::HashMap; diff --git a/tests/run-make/wasm-custom-sections-opt/rmake.rs b/tests/run-make/wasm-custom-sections-opt/rmake.rs index 634683adc220..24570d8baf5a 100644 --- a/tests/run-make/wasm-custom-sections-opt/rmake.rs +++ b/tests/run-make/wasm-custom-sections-opt/rmake.rs @@ -1,5 +1,4 @@ //@ only-wasm32-wasip1 -extern crate run_make_support; use run_make_support::{tmp_dir, wasmparser, rustc}; use std::collections::HashMap; diff --git a/tests/run-make/wasm-export-all-symbols/rmake.rs b/tests/run-make/wasm-export-all-symbols/rmake.rs index 400d6db5651c..50c99d027d5a 100644 --- a/tests/run-make/wasm-export-all-symbols/rmake.rs +++ b/tests/run-make/wasm-export-all-symbols/rmake.rs @@ -1,7 +1,5 @@ //@ only-wasm32-wasip1 -extern crate run_make_support; - use run_make_support::{tmp_dir, wasmparser, rustc}; use std::collections::HashMap; use std::path::Path; diff --git a/tests/run-make/wasm-import-module/rmake.rs b/tests/run-make/wasm-import-module/rmake.rs index 1b814e9ccce3..333d0df4653f 100644 --- a/tests/run-make/wasm-import-module/rmake.rs +++ b/tests/run-make/wasm-import-module/rmake.rs @@ -1,7 +1,5 @@ //@ only-wasm32-wasip1 -extern crate run_make_support; - use run_make_support::{tmp_dir, wasmparser, rustc}; use std::collections::HashMap; use wasmparser::TypeRef::Func; diff --git a/tests/run-make/wasm-panic-small/rmake.rs b/tests/run-make/wasm-panic-small/rmake.rs index bffa311d93a1..373b966401ce 100644 --- a/tests/run-make/wasm-panic-small/rmake.rs +++ b/tests/run-make/wasm-panic-small/rmake.rs @@ -1,8 +1,6 @@ //@ only-wasm32-wasip1 #![deny(warnings)] -extern crate run_make_support; - use run_make_support::{rustc, tmp_dir}; fn main() { diff --git a/tests/run-make/wasm-spurious-import/rmake.rs b/tests/run-make/wasm-spurious-import/rmake.rs index 8f716061d28b..458c7bfccb74 100644 --- a/tests/run-make/wasm-spurious-import/rmake.rs +++ b/tests/run-make/wasm-spurious-import/rmake.rs @@ -1,7 +1,5 @@ //@ only-wasm32-wasip1 -extern crate run_make_support; - use run_make_support::{rustc, tmp_dir, wasmparser}; use std::collections::HashMap; diff --git a/tests/run-make/wasm-stringify-ints-small/rmake.rs b/tests/run-make/wasm-stringify-ints-small/rmake.rs index 5efbfee8d383..9fac0c0c215d 100644 --- a/tests/run-make/wasm-stringify-ints-small/rmake.rs +++ b/tests/run-make/wasm-stringify-ints-small/rmake.rs @@ -1,8 +1,6 @@ //@ only-wasm32-wasip1 #![deny(warnings)] -extern crate run_make_support; - use run_make_support::{rustc, tmp_dir}; fn main() { diff --git a/tests/run-make/wasm-symbols-different-module/rmake.rs b/tests/run-make/wasm-symbols-different-module/rmake.rs index 88bd16a404c7..521d2c31ee61 100644 --- a/tests/run-make/wasm-symbols-different-module/rmake.rs +++ b/tests/run-make/wasm-symbols-different-module/rmake.rs @@ -1,5 +1,4 @@ //@ only-wasm32-wasip1 -extern crate run_make_support; use run_make_support::{rustc, tmp_dir, wasmparser}; use std::collections::{HashMap, HashSet}; diff --git a/tests/run-make/wasm-symbols-not-exported/rmake.rs b/tests/run-make/wasm-symbols-not-exported/rmake.rs index c9207f70ae5f..1b020b67a385 100644 --- a/tests/run-make/wasm-symbols-not-exported/rmake.rs +++ b/tests/run-make/wasm-symbols-not-exported/rmake.rs @@ -1,5 +1,4 @@ //@ only-wasm32-wasip1 -extern crate run_make_support; use run_make_support::{rustc, tmp_dir, wasmparser}; use std::path::Path; diff --git a/tests/run-make/wasm-symbols-not-imported/rmake.rs b/tests/run-make/wasm-symbols-not-imported/rmake.rs index 4d41dc7c0aa8..a653ab61b2c0 100644 --- a/tests/run-make/wasm-symbols-not-imported/rmake.rs +++ b/tests/run-make/wasm-symbols-not-imported/rmake.rs @@ -1,5 +1,4 @@ //@ only-wasm32-wasip1 -extern crate run_make_support; use run_make_support::{rustc, tmp_dir, wasmparser}; use std::path::Path; From dbe2f51d6240c33c2c1aa3df6ecc7e19c32bd074 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 2 May 2024 18:34:30 +0200 Subject: [PATCH 250/279] const_eval_select: add tracking issue --- library/core/src/intrinsics.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 3318a8ffa554..d23764abe7a7 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2578,8 +2578,7 @@ extern "rust-intrinsic" { /// /// Currently such an assertion would always succeed; until Rust decides /// otherwise, that principle should not be violated. -#[rustc_const_unstable(feature = "const_eval_select", issue = "none")] -#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_const_unstable(feature = "const_eval_select", issue = "124625")] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn const_eval_select( From dba1849c22b6c10af98e720cfa6dd6868f029e4a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 2 May 2024 18:47:36 +0200 Subject: [PATCH 251/279] interpret: hide some reexports in rustdoc --- compiler/rustc_const_eval/src/interpret/mod.rs | 1 + src/tools/miri/src/lib.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs index 7ede90ad13f1..7d7b421f8693 100644 --- a/compiler/rustc_const_eval/src/interpret/mod.rs +++ b/compiler/rustc_const_eval/src/interpret/mod.rs @@ -18,6 +18,7 @@ mod util; mod validity; mod visitor; +#[doc(no_inline)] pub use rustc_middle::mir::interpret::*; // have all the `interpret` symbols in one place: here pub use self::eval_context::{format_interp_error, Frame, FrameInfo, InterpCx, StackPopCleanup}; diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 44727e01ea22..f47c84842b17 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -89,8 +89,10 @@ mod shims; // Establish a "crate-wide prelude": we often import `crate::*`. // Make all those symbols available in the same place as our own. +#[doc(no_inline)] pub use rustc_const_eval::interpret::*; // Resolve ambiguity. +#[doc(no_inline)] pub use rustc_const_eval::interpret::{self, AllocMap, PlaceTy, Provenance as _}; pub use crate::shims::env::{EnvVars, EvalContextExt as _}; From ff2ff9790436ca16a69c2237a5a8b8a88c69cdbf Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 2 May 2024 09:14:39 +0200 Subject: [PATCH 252/279] variable-precision float operations behave non-deterministically --- library/std/src/f32.rs | 145 ++++++++++++++++++++++++----------------- library/std/src/f64.rs | 145 ++++++++++++++++++++++++----------------- 2 files changed, 174 insertions(+), 116 deletions(-) diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index de9bde51f2a3..4fc82fec0adb 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -371,9 +371,10 @@ impl f32 { /// It might have a different sequence of rounding operations than `powf`, /// so the results are not guaranteed to agree. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -393,9 +394,10 @@ impl f32 { /// Raises a number to a floating point power. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -444,9 +446,10 @@ impl f32 { /// Returns `e^(self)`, (the exponential function). /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -470,9 +473,10 @@ impl f32 { /// Returns `2^(self)`. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -494,9 +498,10 @@ impl f32 { /// Returns the natural logarithm of the number. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -524,9 +529,10 @@ impl f32 { /// `self.log2()` can produce more accurate results for base 2, and /// `self.log10()` can produce more accurate results for base 10. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -548,9 +554,10 @@ impl f32 { /// Returns the base 2 logarithm of the number. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -572,9 +579,10 @@ impl f32 { /// Returns the base 10 logarithm of the number. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -599,9 +607,10 @@ impl f32 { /// * If `self <= other`: `0.0` /// * Else: `self - other` /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `fdimf` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -637,9 +646,10 @@ impl f32 { /// Returns the cube root of a number. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `cbrtf` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -666,9 +676,10 @@ impl f32 { /// right-angle triangle with other sides having length `x.abs()` and /// `y.abs()`. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `hypotf` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -693,9 +704,10 @@ impl f32 { /// Computes the sine of a number (in radians). /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -716,9 +728,10 @@ impl f32 { /// Computes the cosine of a number (in radians). /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -739,9 +752,10 @@ impl f32 { /// Computes the tangent of a number (in radians). /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `tanf` from libc on Unix and /// Windows. Note that this might change in the future. /// @@ -765,9 +779,10 @@ impl f32 { /// the range [-pi/2, pi/2] or NaN if the number is outside the range /// [-1, 1]. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `asinf` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -794,9 +809,10 @@ impl f32 { /// the range [0, pi] or NaN if the number is outside the range /// [-1, 1]. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `acosf` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -822,9 +838,10 @@ impl f32 { /// Computes the arctangent of a number. Return value is in radians in the /// range [-pi/2, pi/2]; /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `atanf` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -854,9 +871,10 @@ impl f32 { /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]` /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)` /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `atan2f` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -890,9 +908,10 @@ impl f32 { /// Simultaneously computes the sine and cosine of the number, `x`. Returns /// `(sin(x), cos(x))`. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `(f32::sin(x), /// f32::cos(x))`. Note that this might change in the future. /// @@ -919,9 +938,10 @@ impl f32 { /// Returns `e^(self) - 1` in a way that is accurate even if the /// number is close to zero. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `expm1f` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -947,9 +967,10 @@ impl f32 { /// Returns `ln(1+n)` (natural logarithm) more accurately than if /// the operations were performed separately. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `log1pf` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -975,9 +996,10 @@ impl f32 { /// Hyperbolic sine function. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `sinhf` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -1004,9 +1026,10 @@ impl f32 { /// Hyperbolic cosine function. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `coshf` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -1033,9 +1056,10 @@ impl f32 { /// Hyperbolic tangent function. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `tanhf` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -1062,9 +1086,10 @@ impl f32 { /// Inverse hyperbolic sine function. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -1089,9 +1114,10 @@ impl f32 { /// Inverse hyperbolic cosine function. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -1118,9 +1144,10 @@ impl f32 { /// Inverse hyperbolic tangent function. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -1143,9 +1170,10 @@ impl f32 { /// Gamma function. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `tgammaf` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -1171,9 +1199,10 @@ impl f32 { /// /// The integer part of the tuple indicates the sign of the gamma function. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `lgamma_r` from libc on Unix /// and Windows. Note that this might change in the future. /// diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index 944186d602c8..f8c66a3e7175 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -371,9 +371,10 @@ impl f64 { /// It might have a different sequence of rounding operations than `powf`, /// so the results are not guaranteed to agree. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -393,9 +394,10 @@ impl f64 { /// Raises a number to a floating point power. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -444,9 +446,10 @@ impl f64 { /// Returns `e^(self)`, (the exponential function). /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -470,9 +473,10 @@ impl f64 { /// Returns `2^(self)`. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -494,9 +498,10 @@ impl f64 { /// Returns the natural logarithm of the number. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -524,9 +529,10 @@ impl f64 { /// `self.log2()` can produce more accurate results for base 2, and /// `self.log10()` can produce more accurate results for base 10. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -548,9 +554,10 @@ impl f64 { /// Returns the base 2 logarithm of the number. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -572,9 +579,10 @@ impl f64 { /// Returns the base 10 logarithm of the number. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -599,9 +607,10 @@ impl f64 { /// * If `self <= other`: `0.0` /// * Else: `self - other` /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `fdim` from libc on Unix and /// Windows. Note that this might change in the future. /// @@ -637,9 +646,10 @@ impl f64 { /// Returns the cube root of a number. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `cbrt` from libc on Unix and /// Windows. Note that this might change in the future. /// @@ -666,9 +676,10 @@ impl f64 { /// right-angle triangle with other sides having length `x.abs()` and /// `y.abs()`. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `hypot` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -693,9 +704,10 @@ impl f64 { /// Computes the sine of a number (in radians). /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -716,9 +728,10 @@ impl f64 { /// Computes the cosine of a number (in radians). /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -739,9 +752,10 @@ impl f64 { /// Computes the tangent of a number (in radians). /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `tan` from libc on Unix and /// Windows. Note that this might change in the future. /// @@ -765,9 +779,10 @@ impl f64 { /// the range [-pi/2, pi/2] or NaN if the number is outside the range /// [-1, 1]. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `asin` from libc on Unix and /// Windows. Note that this might change in the future. /// @@ -794,9 +809,10 @@ impl f64 { /// the range [0, pi] or NaN if the number is outside the range /// [-1, 1]. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `acos` from libc on Unix and /// Windows. Note that this might change in the future. /// @@ -822,9 +838,10 @@ impl f64 { /// Computes the arctangent of a number. Return value is in radians in the /// range [-pi/2, pi/2]; /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `atan` from libc on Unix and /// Windows. Note that this might change in the future. /// @@ -854,9 +871,10 @@ impl f64 { /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]` /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)` /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `atan2` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -890,9 +908,10 @@ impl f64 { /// Simultaneously computes the sine and cosine of the number, `x`. Returns /// `(sin(x), cos(x))`. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `(f64::sin(x), /// f64::cos(x))`. Note that this might change in the future. /// @@ -919,9 +938,10 @@ impl f64 { /// Returns `e^(self) - 1` in a way that is accurate even if the /// number is close to zero. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `expm1` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -947,9 +967,10 @@ impl f64 { /// Returns `ln(1+n)` (natural logarithm) more accurately than if /// the operations were performed separately. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `log1p` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -975,9 +996,10 @@ impl f64 { /// Hyperbolic sine function. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `sinh` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -1004,9 +1026,10 @@ impl f64 { /// Hyperbolic cosine function. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `cosh` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -1033,9 +1056,10 @@ impl f64 { /// Hyperbolic tangent function. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `tanh` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -1062,9 +1086,10 @@ impl f64 { /// Inverse hyperbolic sine function. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -1089,9 +1114,10 @@ impl f64 { /// Inverse hyperbolic cosine function. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -1118,9 +1144,10 @@ impl f64 { /// Inverse hyperbolic tangent function. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// /// # Examples /// @@ -1143,9 +1170,10 @@ impl f64 { /// Gamma function. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `tgamma` from libc on Unix /// and Windows. Note that this might change in the future. /// @@ -1171,9 +1199,10 @@ impl f64 { /// /// The integer part of the tuple indicates the sign of the gamma function. /// - /// # Platform-specific precision + /// # Unspecified precision /// - /// The precision of this function varies by platform and Rust version. + /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and + /// can even differ within the same execution from one invocation to the next. /// This function currently corresponds to the `lgamma_r` from libc on Unix /// and Windows. Note that this might change in the future. /// From 0a03b0961a3a10a8ff5613f5500f8d1eef836f08 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 2 May 2024 11:35:21 +0200 Subject: [PATCH 253/279] run-make-support: add support for stdin input with rustc/rustdoc --- src/tools/run-make-support/src/cc.rs | 5 +++ src/tools/run-make-support/src/clang.rs | 5 +++ src/tools/run-make-support/src/lib.rs | 18 ++++----- .../run-make-support/src/llvm_readobj.rs | 6 +++ src/tools/run-make-support/src/rustc.rs | 38 ++++++++++++++++-- src/tools/run-make-support/src/rustdoc.rs | 39 +++++++++++++++++-- 6 files changed, 94 insertions(+), 17 deletions(-) diff --git a/src/tools/run-make-support/src/cc.rs b/src/tools/run-make-support/src/cc.rs index a2d51902652b..fbb57c7154e5 100644 --- a/src/tools/run-make-support/src/cc.rs +++ b/src/tools/run-make-support/src/cc.rs @@ -71,6 +71,11 @@ impl Cc { self } + + /// Get the [`Output`][::std::process::Output] of the finished process. + pub fn output(&mut self) -> ::std::process::Output { + self.cmd.output().expect("failed to get output of finished process") + } } /// `EXTRACFLAGS` diff --git a/src/tools/run-make-support/src/clang.rs b/src/tools/run-make-support/src/clang.rs index ed9f8383dc3a..c30ba29ed76d 100644 --- a/src/tools/run-make-support/src/clang.rs +++ b/src/tools/run-make-support/src/clang.rs @@ -70,4 +70,9 @@ impl Clang { self.cmd.arg(format!("-fuse-ld={ld}")); self } + + /// Get the [`Output`][::std::process::Output] of the finished process. + pub fn output(&mut self) -> ::std::process::Output { + self.cmd.output().expect("failed to get output of finished process") + } } diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index a874c1313b51..239f90b23c98 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -144,7 +144,7 @@ pub fn set_host_rpath(cmd: &mut Command) { } /// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct -/// containing a `cmd: Command` field. The provided helpers are: +/// containing a `cmd: Command` field and a `output` function. The provided helpers are: /// /// 1. Generic argument acceptors: `arg` and `args` (delegated to [`Command`]). These are intended /// to be *fallback* argument acceptors, when specific helpers don't make sense. Prefer to add @@ -160,7 +160,12 @@ pub fn set_host_rpath(cmd: &mut Command) { /// Example usage: /// /// ```ignore (illustrative) -/// struct CommandWrapper { cmd: Command } +/// struct CommandWrapper { cmd: Command } // <- required `cmd` field +/// +/// impl CommandWrapper { +/// /// Get the [`Output`][::std::process::Output] of the finished process. +/// pub fn output(&mut self) -> Output { /* ... */ } // <- required `output()` method +/// } /// /// crate::impl_common_helpers!(CommandWrapper); /// @@ -231,18 +236,13 @@ macro_rules! impl_common_helpers { self } - /// Get the [`Output`][::std::process::Output] of the finished process. - pub fn output(&mut self) -> ::std::process::Output { - self.cmd.output().expect("failed to get output of finished process") - } - /// Run the constructed command and assert that it is successfully run. #[track_caller] pub fn run(&mut self) -> ::std::process::Output { let caller_location = ::std::panic::Location::caller(); let caller_line_number = caller_location.line(); - let output = self.cmd.output().unwrap(); + let output = self.output(); if !output.status.success() { handle_failed_output(&self.cmd, output, caller_line_number); } @@ -255,7 +255,7 @@ macro_rules! impl_common_helpers { let caller_location = ::std::panic::Location::caller(); let caller_line_number = caller_location.line(); - let output = self.cmd.output().unwrap(); + let output = self.output(); if output.status.success() { handle_failed_output(&self.cmd, output, caller_line_number); } diff --git a/src/tools/run-make-support/src/llvm_readobj.rs b/src/tools/run-make-support/src/llvm_readobj.rs index 32ea07e932ed..4e1f2b002f30 100644 --- a/src/tools/run-make-support/src/llvm_readobj.rs +++ b/src/tools/run-make-support/src/llvm_readobj.rs @@ -41,4 +41,10 @@ impl LlvmReadobj { self.cmd.arg("--file-header"); self } + + /// Get the [`Output`][::std::process::Output] of the finished process. + #[track_caller] + pub fn output(&mut self) -> ::std::process::Output { + self.cmd.output().expect("failed to get output of finished process") + } } diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index ddaae3236c2b..37539528ab3f 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -1,7 +1,8 @@ use std::env; use std::ffi::OsString; +use std::io::Write; use std::path::Path; -use std::process::{Command, Output}; +use std::process::{Command, Output, Stdio}; use crate::{handle_failed_output, set_host_rpath, tmp_dir}; @@ -19,6 +20,7 @@ pub fn aux_build() -> Rustc { #[derive(Debug)] pub struct Rustc { cmd: Command, + stdin: Option>, } crate::impl_common_helpers!(Rustc); @@ -37,14 +39,14 @@ impl Rustc { /// Construct a new `rustc` invocation. pub fn new() -> Self { let cmd = setup_common(); - Self { cmd } + Self { cmd, stdin: None } } /// Construct a new `rustc` invocation with `aux_build` preset (setting `--crate-type=lib`). pub fn new_aux_build() -> Self { let mut cmd = setup_common(); cmd.arg("--crate-type=lib"); - Self { cmd } + Self { cmd, stdin: None } } // Argument provider methods @@ -161,12 +163,40 @@ impl Rustc { self } + /// Specify a stdin input + pub fn stdin>(&mut self, input: I) -> &mut Self { + self.stdin = Some(input.as_ref().to_vec().into_boxed_slice()); + self + } + + /// Get the [`Output`][::std::process::Output] of the finished process. + #[track_caller] + pub fn output(&mut self) -> ::std::process::Output { + // let's make sure we piped all the input and outputs + self.cmd.stdin(Stdio::piped()); + self.cmd.stdout(Stdio::piped()); + self.cmd.stderr(Stdio::piped()); + + if let Some(input) = &self.stdin { + let mut child = self.cmd.spawn().unwrap(); + + { + let mut stdin = child.stdin.take().unwrap(); + stdin.write_all(input.as_ref()).unwrap(); + } + + child.wait_with_output().expect("failed to get output of finished process") + } else { + self.cmd.output().expect("failed to get output of finished process") + } + } + #[track_caller] pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output { let caller_location = std::panic::Location::caller(); let caller_line_number = caller_location.line(); - let output = self.cmd.output().unwrap(); + let output = self.output(); if output.status.code().unwrap() != code { handle_failed_output(&self.cmd, output, caller_line_number); } diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index 1054ac83c103..c2c4f2e68e2f 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -1,6 +1,7 @@ use std::env; +use std::io::Write; use std::path::Path; -use std::process::{Command, Output}; +use std::process::{Command, Output, Stdio}; use crate::{handle_failed_output, set_host_rpath}; @@ -17,6 +18,7 @@ pub fn rustdoc() -> Rustdoc { #[derive(Debug)] pub struct Rustdoc { cmd: Command, + stdin: Option>, } crate::impl_common_helpers!(Rustdoc); @@ -32,7 +34,7 @@ impl Rustdoc { /// Construct a bare `rustdoc` invocation. pub fn bare() -> Self { let cmd = setup_common(); - Self { cmd } + Self { cmd, stdin: None } } /// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set. @@ -40,7 +42,7 @@ impl Rustdoc { let mut cmd = setup_common(); let target_rpath_dir = env::var_os("TARGET_RPATH_DIR").unwrap(); cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy())); - Self { cmd } + Self { cmd, stdin: None } } /// Specify path to the input file. @@ -62,12 +64,41 @@ impl Rustdoc { self } + /// Specify a stdin input + pub fn stdin>(&mut self, input: I) -> &mut Self { + self.cmd.stdin(Stdio::piped()); + self.stdin = Some(input.as_ref().to_vec().into_boxed_slice()); + self + } + + /// Get the [`Output`][::std::process::Output] of the finished process. + #[track_caller] + pub fn output(&mut self) -> ::std::process::Output { + // let's make sure we piped all the input and outputs + self.cmd.stdin(Stdio::piped()); + self.cmd.stdout(Stdio::piped()); + self.cmd.stderr(Stdio::piped()); + + if let Some(input) = &self.stdin { + let mut child = self.cmd.spawn().unwrap(); + + { + let mut stdin = child.stdin.take().unwrap(); + stdin.write_all(input.as_ref()).unwrap(); + } + + child.wait_with_output().expect("failed to get output of finished process") + } else { + self.cmd.output().expect("failed to get output of finished process") + } + } + #[track_caller] pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output { let caller_location = std::panic::Location::caller(); let caller_line_number = caller_location.line(); - let output = self.cmd.output().unwrap(); + let output = self.output(); if output.status.code().unwrap() != code { handle_failed_output(&self.cmd, output, caller_line_number); } From 3722eb0b8f07e759dc857865c1b0fbc906253105 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 2 May 2024 13:27:57 +1000 Subject: [PATCH 254/279] Tweak `consts_may_unify`. `ConstKind::Value` is the only variant where control flow leaves the first match on `impl_ct.kind()`, so there is no need for a second match on the same expression later on. --- compiler/rustc_middle/src/ty/fast_reject.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 15f048ab598c..8d7489f5f7e6 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -330,20 +330,19 @@ impl DeepRejectCtxt { } pub fn consts_may_unify(self, obligation_ct: ty::Const<'_>, impl_ct: ty::Const<'_>) -> bool { - match impl_ct.kind() { + let impl_val = match impl_ct.kind() { ty::ConstKind::Expr(_) | ty::ConstKind::Param(_) | ty::ConstKind::Unevaluated(_) | ty::ConstKind::Error(_) => { return true; } - ty::ConstKind::Value(_) => {} + ty::ConstKind::Value(impl_val) => impl_val, ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => { bug!("unexpected impl arg: {:?}", impl_ct) } - } + }; - let k = impl_ct.kind(); match obligation_ct.kind() { ty::ConstKind::Param(_) => match self.treat_obligation_params { TreatParams::ForLookup => false, @@ -358,10 +357,7 @@ impl DeepRejectCtxt { ty::ConstKind::Expr(_) | ty::ConstKind::Unevaluated(_) | ty::ConstKind::Error(_) => { true } - ty::ConstKind::Value(obl) => match k { - ty::ConstKind::Value(imp) => obl == imp, - _ => true, - }, + ty::ConstKind::Value(obl_val) => obl_val == impl_val, ty::ConstKind::Infer(_) => true, From aabb90d25489b02bd87eb2429479379f80ce5564 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 29 Apr 2024 08:38:05 +1000 Subject: [PATCH 255/279] rustc_expand: clean up attributes. Sort them, and remove the unused ones (`lint_reasons` and `proc_macro_span`). --- compiler/rustc_expand/src/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 3c9d2e870683..13e32a6a1e62 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -1,19 +1,19 @@ +// tidy-alphabetical-start +#![allow(internal_features)] +#![allow(rustc::diagnostic_outside_of_impl)] #![doc(rust_logo)] -#![feature(rustdoc_internals)] #![feature(array_windows)] #![feature(associated_type_defaults)] #![feature(if_let_guard)] #![feature(let_chains)] -#![feature(lint_reasons)] #![feature(macro_metavar_expr)] #![feature(map_try_insert)] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_internals)] -#![feature(proc_macro_span)] +#![feature(rustdoc_internals)] #![feature(try_blocks)] #![feature(yeet_expr)] -#![allow(rustc::diagnostic_outside_of_impl)] -#![allow(internal_features)] +// tidy-alphabetical-end extern crate proc_macro as pm; From d8178569784a78f6e52eeb281c106de801bb398a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 30 Apr 2024 08:48:27 +1000 Subject: [PATCH 256/279] Remove an unnecessary re-export of `rustc_span::hygiene`. --- compiler/rustc_expand/src/expand.rs | 2 +- compiler/rustc_expand/src/lib.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 503c9170cab5..64a17eae6741 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -4,7 +4,6 @@ use crate::errors::{ IncompleteParse, RecursionLimitReached, RemoveExprNotSupported, RemoveNodeNotSupported, UnsupportedKeyValue, WrongFragmentKind, }; -use crate::hygiene::SyntaxContext; use crate::mbe::diagnostics::annotate_err_with_kind; use crate::module::{mod_dir_path, parse_external_mod, DirOwnership, ParsedExternalMod}; use crate::placeholders::{placeholder, PlaceholderExpander}; @@ -32,6 +31,7 @@ use rustc_session::lint::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS}; use rustc_session::lint::BuiltinLintDiag; use rustc_session::parse::feature_err; use rustc_session::{Limit, Session}; +use rustc_span::hygiene::SyntaxContext; use rustc_span::symbol::{sym, Ident}; use rustc_span::{ErrorGuaranteed, FileName, LocalExpnId, Span}; diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 13e32a6a1e62..2e52a7f9a7da 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -21,7 +21,6 @@ mod placeholders; mod proc_macro_server; pub use mbe::macro_rules::compile_declarative_macro; -pub(crate) use rustc_span::hygiene; pub mod base; pub mod build; #[macro_use] From 7c6d36345f8abe55c4fa57e6d194219fcc954152 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 30 Apr 2024 08:49:58 +1000 Subject: [PATCH 257/279] Remove an unnecessary `#[macro_use]`. --- compiler/rustc_expand/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 2e52a7f9a7da..6216965f7bfe 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -23,7 +23,6 @@ mod proc_macro_server; pub use mbe::macro_rules::compile_declarative_macro; pub mod base; pub mod build; -#[macro_use] pub mod config; pub mod errors; pub mod expand; From 3f055893b40a854441daa23aa192220bd614bd84 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 30 Apr 2024 10:08:52 +1000 Subject: [PATCH 258/279] Remove unused `ExpCtxt` methods. --- compiler/rustc_expand/src/build.rs | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 83f120525bc5..1b6e191c2eb0 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -175,20 +175,6 @@ impl<'a> ExtCtxt<'a> { ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr) } } - pub fn stmt_let_pat(&self, sp: Span, pat: P, ex: P) -> ast::Stmt { - let local = P(ast::Local { - pat, - ty: None, - id: ast::DUMMY_NODE_ID, - kind: LocalKind::Init(ex), - span: sp, - colon_sp: None, - attrs: AttrVec::new(), - tokens: None, - }); - self.stmt_local(local, sp) - } - pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: P) -> ast::Stmt { self.stmt_let_ty(sp, mutbl, ident, None, ex) } @@ -278,10 +264,6 @@ impl<'a> ExtCtxt<'a> { self.expr_ident(span, Ident::with_dummy_span(kw::SelfLower)) } - pub fn expr_field(&self, span: Span, expr: P, field: Ident) -> P { - self.expr(span, ast::ExprKind::Field(expr, field)) - } - pub fn expr_macro_call(&self, span: Span, call: P) -> P { self.expr(span, ast::ExprKind::MacCall(call)) } @@ -394,11 +376,6 @@ impl<'a> ExtCtxt<'a> { self.expr(span, ast::ExprKind::Lit(lit)) } - pub fn expr_char(&self, span: Span, ch: char) -> P { - let lit = token::Lit::new(token::Char, literal::escape_char_symbol(ch), None); - self.expr(span, ast::ExprKind::Lit(lit)) - } - pub fn expr_byte_str(&self, span: Span, bytes: Vec) -> P { let lit = token::Lit::new(token::ByteStr, literal::escape_byte_str_symbol(&bytes), None); self.expr(span, ast::ExprKind::Lit(lit)) @@ -414,10 +391,6 @@ impl<'a> ExtCtxt<'a> { self.expr_addr_of(sp, self.expr_array(sp, exprs)) } - pub fn expr_cast(&self, sp: Span, expr: P, ty: P) -> P { - self.expr(sp, ast::ExprKind::Cast(expr, ty)) - } - pub fn expr_some(&self, sp: Span, expr: P) -> P { let some = self.std_path(&[sym::option, sym::Option, sym::Some]); self.expr_call_global(sp, some, thin_vec![expr]) From 189a8a692549f240d31b34138c8fc26dd8b6d118 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 30 Apr 2024 10:20:05 +1000 Subject: [PATCH 259/279] De-`pub` some `rustc_expand` modules. --- compiler/rustc_expand/src/lib.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 6216965f7bfe..c2c3b777699c 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -17,25 +17,23 @@ extern crate proc_macro as pm; +mod build; +mod errors; +// FIXME(Nilstrieb) Translate macro_rules diagnostics +#[allow(rustc::untranslatable_diagnostic)] +mod mbe; mod placeholders; mod proc_macro_server; pub use mbe::macro_rules::compile_declarative_macro; pub mod base; -pub mod build; pub mod config; -pub mod errors; pub mod expand; pub mod module; - // FIXME(Nilstrieb) Translate proc_macro diagnostics #[allow(rustc::untranslatable_diagnostic)] pub mod proc_macro; -// FIXME(Nilstrieb) Translate macro_rules diagnostics -#[allow(rustc::untranslatable_diagnostic)] -pub(crate) mod mbe; - // HACK(Centril, #64197): These shouldn't really be here. // Rather, they should be with their respective modules which are defined in other crates. // However, since for now constructing a `ParseSess` sorta requires `config` from this crate, From e809df6ed42f4c2c5cd37b8711f88f61c38332c8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 30 Apr 2024 10:52:42 +1000 Subject: [PATCH 260/279] Remove unnecessary re-export of `MacroKind`. --- compiler/rustc_expand/src/base.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 6fe74edbd70a..ed4cb32d2dbe 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -21,7 +21,7 @@ use rustc_session::config::CollapseMacroDebuginfo; use rustc_session::{parse::ParseSess, Limit, Session}; use rustc_span::def_id::{CrateNum, DefId, LocalDefId}; use rustc_span::edition::Edition; -use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId}; +use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind}; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{FileName, Span, DUMMY_SP}; @@ -32,8 +32,6 @@ use std::path::{Path, PathBuf}; use std::rc::Rc; use thin_vec::ThinVec; -pub(crate) use rustc_span::hygiene::MacroKind; - // When adding new variants, make sure to // adjust the `visit_*` / `flat_map_*` calls in `InvocationCollector` // to use `assign_id!` From d7f5319b6db4cac89b7989ecfbb1f511a95826e6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 30 Apr 2024 12:03:08 +1000 Subject: [PATCH 261/279] Inline and remove three `DummyResult` methods. They each have a single call site. --- compiler/rustc_expand/src/base.rs | 54 +++++++++++++------------------ 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index ed4cb32d2dbe..12868a666056 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -571,35 +571,6 @@ impl DummyResult { tokens: None, }) } - - /// A plain dummy pattern. - pub fn raw_pat(sp: Span) -> ast::Pat { - ast::Pat { id: ast::DUMMY_NODE_ID, kind: PatKind::Wild, span: sp, tokens: None } - } - - /// A plain dummy type. - pub fn raw_ty(sp: Span) -> P { - // FIXME(nnethercote): you might expect `ast::TyKind::Dummy` to be used here, but some - // values produced here end up being lowered to HIR, which `ast::TyKind::Dummy` does not - // support, so we use an empty tuple instead. - P(ast::Ty { - id: ast::DUMMY_NODE_ID, - kind: ast::TyKind::Tup(ThinVec::new()), - span: sp, - tokens: None, - }) - } - - /// A plain dummy crate. - pub fn raw_crate() -> ast::Crate { - ast::Crate { - attrs: Default::default(), - items: Default::default(), - spans: Default::default(), - id: ast::DUMMY_NODE_ID, - is_placeholder: Default::default(), - } - } } impl MacResult for DummyResult { @@ -608,7 +579,12 @@ impl MacResult for DummyResult { } fn make_pat(self: Box) -> Option> { - Some(P(DummyResult::raw_pat(self.span))) + Some(P(ast::Pat { + id: ast::DUMMY_NODE_ID, + kind: PatKind::Wild, + span: self.span, + tokens: None, + })) } fn make_items(self: Box) -> Option; 1]>> { @@ -636,7 +612,15 @@ impl MacResult for DummyResult { } fn make_ty(self: Box) -> Option> { - Some(DummyResult::raw_ty(self.span)) + // FIXME(nnethercote): you might expect `ast::TyKind::Dummy` to be used here, but some + // values produced here end up being lowered to HIR, which `ast::TyKind::Dummy` does not + // support, so we use an empty tuple instead. + Some(P(ast::Ty { + id: ast::DUMMY_NODE_ID, + kind: ast::TyKind::Tup(ThinVec::new()), + span: self.span, + tokens: None, + })) } fn make_arms(self: Box) -> Option> { @@ -668,7 +652,13 @@ impl MacResult for DummyResult { } fn make_crate(self: Box) -> Option { - Some(DummyResult::raw_crate()) + Some(ast::Crate { + attrs: Default::default(), + items: Default::default(), + spans: Default::default(), + id: ast::DUMMY_NODE_ID, + is_placeholder: Default::default(), + }) } } From c9c964fc379966a9fd932e1b5ac8a3327e424cd3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 1 May 2024 09:27:20 +1000 Subject: [PATCH 262/279] Fix some comment formatting. --- compiler/rustc_expand/src/config.rs | 9 +++++---- compiler/rustc_expand/src/expand.rs | 5 +++-- compiler/rustc_expand/src/mbe/diagnostics.rs | 3 ++- compiler/rustc_expand/src/mbe/macro_rules.rs | 11 ++++++----- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index b554a5ccd196..897420a11cdf 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -99,10 +99,11 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) - // If the declared feature is unstable, record it. if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name) { (f.set_enabled)(&mut features); - // When the ICE comes from core, alloc or std (approximation of the standard library), there's a chance - // that the person hitting the ICE may be using -Zbuild-std or similar with an untested target. - // The bug is probably in the standard library and not the compiler in that case, but that doesn't - // really matter - we want a bug report. + // When the ICE comes from core, alloc or std (approximation of the standard + // library), there's a chance that the person hitting the ICE may be using + // -Zbuild-std or similar with an untested target. The bug is probably in the + // standard library and not the compiler in that case, but that doesn't really + // matter - we want a bug report. if features.internal(name) && ![sym::core, sym::alloc, sym::std].contains(&crate_name) { diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 64a17eae6741..35722c949093 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -505,8 +505,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let (fragment, collected_invocations) = self.collect_invocations(fragment, &derive_placeholders); - // We choose to expand any derive invocations associated with this macro invocation - // *before* any macro invocations collected from the output fragment + // We choose to expand any derive invocations associated with this macro + // invocation *before* any macro invocations collected from the output + // fragment. derive_invocations.extend(collected_invocations); (fragment, derive_invocations) } diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index 5d6c3e8aa3a4..464361cb4020 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -28,7 +28,8 @@ pub(super) fn failed_to_match_macro<'cx>( ) -> Box { let psess = &cx.sess.psess; - // An error occurred, try the expansion again, tracking the expansion closely for better diagnostics. + // An error occurred, try the expansion again, tracking the expansion closely for better + // diagnostics. let mut tracker = CollectTrackerAndEmitter::new(cx, sp); let try_success_result = try_match_macro(psess, name, &arg, lhses, &mut tracker); diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index df2643ad1dde..470bde232d72 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -157,8 +157,8 @@ pub(super) trait Tracker<'matcher> { /// This is called before trying to match next MatcherLoc on the current token. fn before_match_loc(&mut self, _parser: &TtParser, _matcher: &'matcher MatcherLoc) {} - /// This is called after an arm has been parsed, either successfully or unsuccessfully. When this is called, - /// `before_match_loc` was called at least once (with a `MatcherLoc::Eof`). + /// This is called after an arm has been parsed, either successfully or unsuccessfully. When + /// this is called, `before_match_loc` was called at least once (with a `MatcherLoc::Eof`). fn after_arm(&mut self, _result: &NamedParseResult) {} /// For tracing. @@ -169,7 +169,8 @@ pub(super) trait Tracker<'matcher> { } } -/// A noop tracker that is used in the hot path of the expansion, has zero overhead thanks to monomorphization. +/// A noop tracker that is used in the hot path of the expansion, has zero overhead thanks to +/// monomorphization. pub(super) struct NoopTracker; impl<'matcher> Tracker<'matcher> for NoopTracker { @@ -492,7 +493,7 @@ pub fn compile_declarative_macro( .pop() .unwrap(); // We don't handle errors here, the driver will abort - // after parsing/expansion. we can report every error in every macro this way. + // after parsing/expansion. We can report every error in every macro this way. check_emission(check_lhs_nt_follows(sess, def, &tt)); return tt; } @@ -528,7 +529,7 @@ pub fn compile_declarative_macro( check_emission(check_rhs(sess, rhs)); } - // don't abort iteration early, so that errors for multiple lhses can be reported + // Don't abort iteration early, so that errors for multiple lhses can be reported. for lhs in &lhses { check_emission(check_lhs_no_empty_seq(sess, slice::from_ref(lhs))); } From 79c4d0202f0c5c44520a424cae34af5e2d30a2cc Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 1 May 2024 09:39:07 +1000 Subject: [PATCH 263/279] Remove unnecessary `pub`s. --- compiler/rustc_expand/src/expand.rs | 10 +++++----- compiler/rustc_expand/src/mbe.rs | 11 ++++++----- compiler/rustc_expand/src/placeholders.rs | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 35722c949093..84fc92a1df5c 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -87,7 +87,7 @@ macro_rules! ast_fragments { } impl AstFragment { - pub fn add_placeholders(&mut self, placeholders: &[NodeId]) { + fn add_placeholders(&mut self, placeholders: &[NodeId]) { if placeholders.is_empty() { return; } @@ -100,14 +100,14 @@ macro_rules! ast_fragments { } } - pub fn make_opt_expr(self) -> Option> { + pub(crate) fn make_opt_expr(self) -> Option> { match self { AstFragment::OptExpr(expr) => expr, _ => panic!("AstFragment::make_* called on the wrong kind of fragment"), } } - pub fn make_method_receiver_expr(self) -> P { + pub(crate) fn make_method_receiver_expr(self) -> P { match self { AstFragment::MethodReceiverExpr(expr) => expr, _ => panic!("AstFragment::make_* called on the wrong kind of fragment"), @@ -125,7 +125,7 @@ macro_rules! ast_fragments { T::fragment_to_output(self) } - pub fn mut_visit_with(&mut self, vis: &mut F) { + pub(crate) fn mut_visit_with(&mut self, vis: &mut F) { match self { AstFragment::OptExpr(opt_expr) => { visit_clobber(opt_expr, |opt_expr| { @@ -958,7 +958,7 @@ pub fn parse_ast_fragment<'a>( }) } -pub fn ensure_complete_parse<'a>( +pub(crate) fn ensure_complete_parse<'a>( parser: &Parser<'a>, macro_path: &ast::Path, kind_name: &str, diff --git a/compiler/rustc_expand/src/mbe.rs b/compiler/rustc_expand/src/mbe.rs index bd6a9b7cb07d..a805c4fcf7b9 100644 --- a/compiler/rustc_expand/src/mbe.rs +++ b/compiler/rustc_expand/src/mbe.rs @@ -4,12 +4,13 @@ //! official terminology: "declarative macros". pub(crate) mod diagnostics; -pub(crate) mod macro_check; -pub(crate) mod macro_parser; pub(crate) mod macro_rules; -pub(crate) mod metavar_expr; -pub(crate) mod quoted; -pub(crate) mod transcribe; + +mod macro_check; +mod macro_parser; +mod metavar_expr; +mod quoted; +mod transcribe; use metavar_expr::MetaVarExpr; use rustc_ast::token::{Delimiter, NonterminalKind, Token, TokenKind}; diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 581d71875bd0..7026425e167c 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -9,7 +9,7 @@ use rustc_span::DUMMY_SP; use smallvec::{smallvec, SmallVec}; use thin_vec::ThinVec; -pub fn placeholder( +pub(crate) fn placeholder( kind: AstFragmentKind, id: ast::NodeId, vis: Option, From 3b6978196da24dd249230532153adc0e662678ac Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 1 May 2024 10:25:55 +1000 Subject: [PATCH 264/279] Tweak `fully_expand_fragment` loop. Control flow never gets past the end of the `ExpandResult::Retry` match arm, due to the `span_bug` and the `continue`. Therefore, the code after the match can only be reached from the `ExpandResult::Ready` arm. This commit moves that code after the match into the `ExpandResult::Ready` arm, avoiding the need for the `continue` in the `ExpandResult::Retry` arm. --- compiler/rustc_expand/src/expand.rs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 84fc92a1df5c..64f21b747a16 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -471,7 +471,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.cx.force_mode = force; let fragment_kind = invoc.fragment_kind; - let (expanded_fragment, new_invocations) = match self.expand_invoc(invoc, &ext.kind) { + match self.expand_invoc(invoc, &ext.kind) { ExpandResult::Ready(fragment) => { let mut derive_invocations = Vec::new(); let derive_placeholders = self @@ -503,13 +503,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }) .unwrap_or_default(); - let (fragment, collected_invocations) = + let (expanded_fragment, collected_invocations) = self.collect_invocations(fragment, &derive_placeholders); // We choose to expand any derive invocations associated with this macro // invocation *before* any macro invocations collected from the output // fragment. derive_invocations.extend(collected_invocations); - (fragment, derive_invocations) + + progress = true; + if expanded_fragments.len() < depth { + expanded_fragments.push(Vec::new()); + } + expanded_fragments[depth - 1].push((expn_id, expanded_fragment)); + invocations.extend(derive_invocations.into_iter().rev()); } ExpandResult::Retry(invoc) => { if force { @@ -520,17 +526,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } else { // Cannot expand, will retry this invocation later. undetermined_invocations.push((invoc, Some(ext))); - continue; } } - }; - - progress = true; - if expanded_fragments.len() < depth { - expanded_fragments.push(Vec::new()); } - expanded_fragments[depth - 1].push((expn_id, expanded_fragment)); - invocations.extend(new_invocations.into_iter().rev()); } self.cx.current_expansion = orig_expansion_data; From 1c15b6ae9c8745cb775b80a48d655c2234135f71 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 1 May 2024 10:50:05 +1000 Subject: [PATCH 265/279] Replace a hard-to-read line. Too clever by half, IMO. --- compiler/rustc_expand/src/expand.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 64f21b747a16..2b93732e28be 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -432,7 +432,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> { break; } invocations = mem::take(&mut undetermined_invocations); - force = !mem::replace(&mut progress, false); + force = !progress; + progress = false; if force && self.monotonic { self.cx.dcx().span_delayed_bug( invocations.last().unwrap().0.span(), From ae7e32880af6b4f2de26ee8842e9995896de21a0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 1 May 2024 10:57:08 +1000 Subject: [PATCH 266/279] Introduce `Invocation::span_mut`. Alongside the existing `Invocation::span`. --- compiler/rustc_expand/src/expand.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 2b93732e28be..f61cebc02562 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -372,6 +372,14 @@ impl Invocation { InvocationKind::Derive { path, .. } => path.span, } } + + fn span_mut(&mut self) -> &mut Span { + match &mut self.kind { + InvocationKind::Bang { span, .. } => span, + InvocationKind::Attr { attr, .. } => &mut attr.span, + InvocationKind::Derive { path, .. } => &mut path.span, + } + } } pub struct MacroExpander<'a, 'b> { @@ -590,11 +598,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { for (invoc, _) in invocations.iter_mut() { let expn_id = invoc.expansion_data.id; let parent_def = self.cx.resolver.invocation_parent(expn_id); - let span = match &mut invoc.kind { - InvocationKind::Bang { span, .. } => span, - InvocationKind::Attr { attr, .. } => &mut attr.span, - InvocationKind::Derive { path, .. } => &mut path.span, - }; + let span = invoc.span_mut(); *span = span.with_parent(Some(parent_def)); } } From 5ac017e772a28b86170eab7a056feb9e42d557c2 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 2 May 2024 10:17:10 +1000 Subject: [PATCH 267/279] Type annotate `repeats`. Because the type is not obvious, and this clarifies things. --- compiler/rustc_expand/src/mbe/transcribe.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index dad83984c8b1..48fdde07f42e 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -117,7 +117,7 @@ pub(super) fn transcribe<'a>( // As we descend in the RHS, we will need to be able to match nested sequences of matchers. // `repeats` keeps track of where we are in matching at each level, with the last element being // the most deeply nested sequence. This is used as a stack. - let mut repeats = Vec::new(); + let mut repeats: Vec<(usize, usize)> = Vec::new(); // `result` contains resulting token stream from the TokenTree we just finished processing. At // the end, this will contain the full result of transcription, but at arbitrary points during From 3a3a15d753649c1701953ecaee6e814497903d73 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 2 May 2024 10:35:23 +1000 Subject: [PATCH 268/279] Refactor `Frame`. It is currently an enum and the `tts` and `idx` fields are repeated across the two variants. This commit splits it into a struct `Frame` and an enum `FrameKind`, to factor out the duplication. The commit also renames `Frame::new` as `Frame::new_delimited` and adds `Frame::new_sequence`. I.e. both variants now have a constructor. --- compiler/rustc_expand/src/mbe/transcribe.rs | 98 +++++++++++---------- 1 file changed, 50 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 48fdde07f42e..011aa95c8a11 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -39,26 +39,32 @@ impl MutVisitor for Marker { } /// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`). -enum Frame<'a> { - Delimited { - tts: &'a [mbe::TokenTree], - idx: usize, - delim: Delimiter, - span: DelimSpan, - spacing: DelimSpacing, - }, - Sequence { - tts: &'a [mbe::TokenTree], - idx: usize, - sep: Option, - kleene_op: KleeneOp, - }, +struct Frame<'a> { + tts: &'a [mbe::TokenTree], + idx: usize, + kind: FrameKind, +} + +enum FrameKind { + Delimited { delim: Delimiter, span: DelimSpan, spacing: DelimSpacing }, + Sequence { sep: Option, kleene_op: KleeneOp }, } impl<'a> Frame<'a> { - /// Construct a new frame around the delimited set of tokens. - fn new(src: &'a mbe::Delimited, span: DelimSpan, spacing: DelimSpacing) -> Frame<'a> { - Frame::Delimited { tts: &src.tts, idx: 0, delim: src.delim, span, spacing } + fn new_delimited(src: &'a mbe::Delimited, span: DelimSpan, spacing: DelimSpacing) -> Frame<'a> { + Frame { + tts: &src.tts, + idx: 0, + kind: FrameKind::Delimited { delim: src.delim, span, spacing }, + } + } + + fn new_sequence( + src: &'a mbe::SequenceRepetition, + sep: Option, + kleene_op: KleeneOp, + ) -> Frame<'a> { + Frame { tts: &src.tts, idx: 0, kind: FrameKind::Sequence { sep, kleene_op } } } } @@ -66,13 +72,9 @@ impl<'a> Iterator for Frame<'a> { type Item = &'a mbe::TokenTree; fn next(&mut self) -> Option<&'a mbe::TokenTree> { - match self { - Frame::Delimited { tts, idx, .. } | Frame::Sequence { tts, idx, .. } => { - let res = tts.get(*idx); - *idx += 1; - res - } - } + let res = self.tts.get(self.idx); + self.idx += 1; + res } } @@ -111,8 +113,11 @@ pub(super) fn transcribe<'a>( // We descend into the RHS (`src`), expanding things as we go. This stack contains the things // we have yet to expand/are still expanding. We start the stack off with the whole RHS. The // choice of spacing values doesn't matter. - let mut stack: SmallVec<[Frame<'_>; 1]> = - smallvec![Frame::new(src, src_span, DelimSpacing::new(Spacing::Alone, Spacing::Alone))]; + let mut stack: SmallVec<[Frame<'_>; 1]> = smallvec![Frame::new_delimited( + src, + src_span, + DelimSpacing::new(Spacing::Alone, Spacing::Alone) + )]; // As we descend in the RHS, we will need to be able to match nested sequences of matchers. // `repeats` keeps track of where we are in matching at each level, with the last element being @@ -142,11 +147,12 @@ pub(super) fn transcribe<'a>( // Otherwise, if we have just reached the end of a sequence and we can keep repeating, // go back to the beginning of the sequence. - if let Frame::Sequence { idx, sep, .. } = stack.last_mut().unwrap() { + let frame = stack.last_mut().unwrap(); + if let FrameKind::Sequence { sep, .. } = &frame.kind { let (repeat_idx, repeat_len) = repeats.last_mut().unwrap(); *repeat_idx += 1; if repeat_idx < repeat_len { - *idx = 0; + frame.idx = 0; if let Some(sep) = sep { result.push(TokenTree::Token(sep.clone(), Spacing::Alone)); } @@ -157,16 +163,16 @@ pub(super) fn transcribe<'a>( // We are done with the top of the stack. Pop it. Depending on what it was, we do // different things. Note that the outermost item must be the delimited, wrapped RHS // that was passed in originally to `transcribe`. - match stack.pop().unwrap() { + match stack.pop().unwrap().kind { // Done with a sequence. Pop from repeats. - Frame::Sequence { .. } => { + FrameKind::Sequence { .. } => { repeats.pop(); } // We are done processing a Delimited. If this is the top-level delimited, we are // done. Otherwise, we unwind the result_stack to append what we have produced to // any previous results. - Frame::Delimited { delim, span, mut spacing, .. } => { + FrameKind::Delimited { delim, span, mut spacing, .. } => { // Hack to force-insert a space after `]` in certain case. // See discussion of the `hex-literal` crate in #114571. if delim == Delimiter::Bracket { @@ -192,7 +198,7 @@ pub(super) fn transcribe<'a>( // We are descending into a sequence. We first make sure that the matchers in the RHS // and the matches in `interp` have the same shape. Otherwise, either the caller or the // macro writer has made a mistake. - seq @ mbe::TokenTree::Sequence(_, delimited) => { + seq @ mbe::TokenTree::Sequence(_, seq_rep) => { match lockstep_iter_size(seq, interp, &repeats) { LockstepIterSize::Unconstrained => { return Err(cx @@ -233,12 +239,11 @@ pub(super) fn transcribe<'a>( // The first time we encounter the sequence we push it to the stack. It // then gets reused (see the beginning of the loop) until we are done // repeating. - stack.push(Frame::Sequence { - idx: 0, - sep: seq.separator.clone(), - tts: &delimited.tts, - kleene_op: seq.kleene.op, - }); + stack.push(Frame::new_sequence( + seq_rep, + seq.separator.clone(), + seq.kleene.op, + )); } } } @@ -294,13 +299,7 @@ pub(super) fn transcribe<'a>( // the previous results (from outside the Delimited). mbe::TokenTree::Delimited(mut span, spacing, delimited) => { mut_visit::visit_delim_span(&mut span, &mut marker); - stack.push(Frame::Delimited { - tts: &delimited.tts, - delim: delimited.delim, - idx: 0, - span, - spacing: *spacing, - }); + stack.push(Frame::new_delimited(delimited, span, *spacing)); result_stack.push(mem::take(&mut result)); } @@ -358,10 +357,13 @@ fn maybe_use_metavar_location( ) -> TokenTree { let undelimited_seq = matches!( stack.last(), - Some(Frame::Sequence { + Some(Frame { tts: [_], - sep: None, - kleene_op: KleeneOp::ZeroOrMore | KleeneOp::OneOrMore, + kind: FrameKind::Sequence { + sep: None, + kleene_op: KleeneOp::ZeroOrMore | KleeneOp::OneOrMore, + .. + }, .. }) ); From 3a3df3e63883c1b624c15bca4d6ca43f7dd03786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 3 May 2024 01:10:22 +0200 Subject: [PATCH 269/279] AST pretty: Use `builtin_syntax` for type ascription --- compiler/rustc_ast/src/ast.rs | 14 ++++++++++---- .../rustc_ast_pretty/src/pprust/state/expr.rs | 15 ++++++++------- .../rustc_ast_pretty/src/pprust/state/item.rs | 1 + 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 12dcbd6d17fd..fa378e19f71a 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1390,7 +1390,7 @@ pub struct StructExpr { // Adding a new variant? Please update `test_expr` in `tests/ui/macros/stringify.rs`. #[derive(Clone, Encodable, Decodable, Debug)] pub enum ExprKind { - /// An array (`[a, b, c, d]`) + /// An array (e.g, `[a, b, c, d]`). Array(ThinVec>), /// Allow anonymous constants from an inline `const` block ConstBlock(AnonConst), @@ -1401,7 +1401,7 @@ pub enum ExprKind { /// This also represents calling the constructor of /// tuple-like ADTs such as tuple structs and enum variants. Call(P, ThinVec>), - /// A method call (e.g. `x.foo::(a, b, c)`). + /// A method call (e.g., `x.foo::(a, b, c)`). MethodCall(Box), /// A tuple (e.g., `(a, b, c, d)`). Tup(ThinVec>), @@ -1413,7 +1413,10 @@ pub enum ExprKind { Lit(token::Lit), /// A cast (e.g., `foo as f64`). Cast(P, P), - /// A type ascription (e.g., `42: usize`). + /// A type ascription (e.g., `builtin # type_ascribe(42, usize)`). + /// + /// Usually not written directly in user code but + /// indirectly via the macro `type_ascribe!(...)`. Type(P, P), /// A `let pat = expr` expression that is only semantically allowed in the condition /// of `if` / `while` expressions. (e.g., `if let 0 = x { .. }`). @@ -1488,7 +1491,10 @@ pub enum ExprKind { /// Output of the `asm!()` macro. InlineAsm(P), - /// Output of the `offset_of!()` macro. + /// An `offset_of` expression (e.g., `builtin # offset_of(Struct, field)`). + /// + /// Usually not written directly in user code but + /// indirectly via the macro `core::mem::offset_of!(...)`. OffsetOf(P, P<[Ident]>), /// A macro invocation; pre-expansion. diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index b5bb781acdfe..93400c67949d 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -422,7 +422,8 @@ impl<'a> State<'a> { self.print_type(ty); } ast::ExprKind::Type(expr, ty) => { - self.word("type_ascribe!("); + self.word("builtin # type_ascribe"); + self.popen(); self.ibox(0); self.print_expr(expr, FixupContext::default()); @@ -431,7 +432,7 @@ impl<'a> State<'a> { self.print_type(ty); self.end(); - self.word(")"); + self.pclose(); } ast::ExprKind::Let(pat, scrutinee, _, _) => { self.print_let(pat, scrutinee, fixup); @@ -657,15 +658,15 @@ impl<'a> State<'a> { ); } ast::ExprKind::InlineAsm(a) => { - // FIXME: This should have its own syntax, distinct from a macro invocation. + // FIXME: Print `builtin # asm` once macro `asm` uses `builtin_syntax`. self.word("asm!"); self.print_inline_asm(a); } ast::ExprKind::FormatArgs(fmt) => { - // FIXME: This should have its own syntax, distinct from a macro invocation. + // FIXME: Print `builtin # format_args` once macro `format_args` uses `builtin_syntax`. self.word("format_args!"); self.popen(); - self.rbox(0, Inconsistent); + self.ibox(0); self.word(reconstruct_format_args_template_string(&fmt.template)); for arg in fmt.arguments.all_args() { self.word_space(","); @@ -677,7 +678,7 @@ impl<'a> State<'a> { ast::ExprKind::OffsetOf(container, fields) => { self.word("builtin # offset_of"); self.popen(); - self.rbox(0, Inconsistent); + self.ibox(0); self.print_type(container); self.word(","); self.space(); @@ -690,8 +691,8 @@ impl<'a> State<'a> { self.print_ident(field); } } - self.pclose(); self.end(); + self.pclose(); } ast::ExprKind::MacCall(m) => self.print_mac(m), ast::ExprKind::Paren(e) => { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index b90182c2b3e6..61398f7d6057 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -238,6 +238,7 @@ impl<'a> State<'a> { self.bclose(item.span, empty); } ast::ItemKind::GlobalAsm(asm) => { + // FIXME: Print `builtin # global_asm` once macro `global_asm` uses `builtin_syntax`. self.head(visibility_qualified(&item.vis, "global_asm!")); self.print_inline_asm(asm); self.word(";"); From d9eb5232b6fea1d902650727f71b4c1bbf69079a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 1 May 2024 17:22:39 -0400 Subject: [PATCH 270/279] Use ObligationCtxt in favor of TraitEngine in many places --- compiler/rustc_hir_analysis/src/autoderef.rs | 36 ++++----- compiler/rustc_hir_typeck/src/coercion.rs | 22 +++--- compiler/rustc_infer/src/traits/mod.rs | 12 +++ compiler/rustc_trait_selection/src/infer.rs | 11 +-- .../src/solve/inspect/analyse.rs | 18 ++--- .../src/traits/coherence.rs | 79 +++++++++---------- .../src/traits/engine.rs | 30 +++++++ .../src/traits/query/evaluate_obligation.rs | 34 ++++---- compiler/rustc_traits/src/codegen.rs | 13 ++- 9 files changed, 142 insertions(+), 113 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index f2ceb4702643..4e85045ef495 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -1,6 +1,6 @@ use crate::errors::AutoDerefReachedRecursionLimit; +use crate::traits; use crate::traits::query::evaluate_obligation::InferCtxtExt; -use crate::traits::{self, TraitEngine, TraitEngineExt}; use rustc_infer::infer::InferCtxt; use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -8,7 +8,7 @@ use rustc_session::Limit; use rustc_span::def_id::LocalDefId; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::Span; -use rustc_trait_selection::traits::StructurallyNormalizeExt; +use rustc_trait_selection::traits::ObligationCtxt; #[derive(Copy, Clone, Debug)] pub enum AutoderefKind { @@ -167,25 +167,19 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { &self, ty: Ty<'tcx>, ) -> Option<(Ty<'tcx>, Vec>)> { - let mut fulfill_cx = >::new(self.infcx); - - let cause = traits::ObligationCause::misc(self.span, self.body_id); - let normalized_ty = match self - .infcx - .at(&cause, self.param_env) - .structurally_normalize(ty, &mut *fulfill_cx) - { - Ok(normalized_ty) => normalized_ty, - Err(errors) => { - // This shouldn't happen, except for evaluate/fulfill mismatches, - // but that's not a reason for an ICE (`predicate_may_hold` is conservative - // by design). - debug!(?errors, "encountered errors while fulfilling"); - return None; - } + let ocx = ObligationCtxt::new(self.infcx); + let Ok(normalized_ty) = ocx.structurally_normalize( + &traits::ObligationCause::misc(self.span, self.body_id), + self.param_env, + ty, + ) else { + // We shouldn't have errors here, except for evaluate/fulfill mismatches, + // but that's not a reason for an ICE (`predicate_may_hold` is conservative + // by design). + // FIXME(-Znext-solver): This *actually* shouldn't happen then. + return None; }; - - let errors = fulfill_cx.select_where_possible(self.infcx); + let errors = ocx.select_where_possible(); if !errors.is_empty() { // This shouldn't happen, except for evaluate/fulfill mismatches, // but that's not a reason for an ICE (`predicate_may_hold` is conservative @@ -194,7 +188,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { return None; } - Some((normalized_ty, fulfill_cx.pending_obligations())) + Some((normalized_ty, ocx.pending_obligations())) } /// Returns the final type we ended up with, which may be an inference diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 825276aef421..e5514fecfbee 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -45,8 +45,7 @@ use rustc_hir::Expr; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult}; -use rustc_infer::traits::TraitEngineExt as _; -use rustc_infer::traits::{IfExpressionCause, MatchExpressionArmCause, TraitEngine}; +use rustc_infer::traits::{IfExpressionCause, MatchExpressionArmCause}; use rustc_infer::traits::{Obligation, PredicateObligation}; use rustc_middle::lint::in_external_macro; use rustc_middle::traits::BuiltinImplSource; @@ -65,7 +64,6 @@ use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; -use rustc_trait_selection::traits::TraitEngineExt as _; use rustc_trait_selection::traits::{ self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt, }; @@ -164,11 +162,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Filter these cases out to make sure our coercion is more accurate. match res { Ok(InferOk { value, obligations }) if self.next_trait_solver() => { - let mut fulfill_cx = >::new(self); - fulfill_cx.register_predicate_obligations(self, obligations); - let errs = fulfill_cx.select_where_possible(self); - if errs.is_empty() { - Ok(InferOk { value, obligations: fulfill_cx.pending_obligations() }) + let ocx = ObligationCtxt::new(self); + ocx.register_obligations(obligations); + if ocx.select_where_possible().is_empty() { + Ok(InferOk { value, obligations: ocx.pending_obligations() }) } else { Err(TypeError::Mismatch) } @@ -631,13 +628,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // but we need to constrain vars before processing goals mentioning // them. Some(ty::PredicateKind::AliasRelate(..)) => { - let mut fulfill_cx = >::new(self); - fulfill_cx.register_predicate_obligation(self, obligation); - let errs = fulfill_cx.select_where_possible(self); - if !errs.is_empty() { + let ocx = ObligationCtxt::new(self); + ocx.register_obligation(obligation); + if !ocx.select_where_possible().is_empty() { return Err(TypeError::Mismatch); } - coercion.obligations.extend(fulfill_cx.pending_obligations()); + coercion.obligations.extend(ocx.pending_obligations()); continue; } _ => { diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index e3611ab28e53..f77a61158618 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -206,6 +206,18 @@ impl<'tcx> FulfillmentError<'tcx> { ) -> FulfillmentError<'tcx> { FulfillmentError { obligation, code, root_obligation } } + + pub fn is_true_error(&self) -> bool { + match self.code { + FulfillmentErrorCode::SelectionError(_) + | FulfillmentErrorCode::ProjectionError(_) + | FulfillmentErrorCode::SubtypeError(_, _) + | FulfillmentErrorCode::ConstEquateError(_, _) => true, + FulfillmentErrorCode::Cycle(_) | FulfillmentErrorCode::Ambiguity { overflow: _ } => { + false + } + } + } } impl<'tcx> PolyTraitObligation<'tcx> { diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index b2400cec42f1..3dc55509dad9 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -1,8 +1,9 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -use crate::traits::{self, ObligationCtxt, SelectionContext, TraitEngineExt as _}; +use crate::traits::{self, ObligationCtxt, SelectionContext}; + use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; -use rustc_infer::traits::{Obligation, TraitEngine, TraitEngineExt as _}; +use rustc_infer::traits::Obligation; use rustc_macros::extension; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::infer::canonical::{Canonical, CanonicalQueryResponse, QueryResponse}; @@ -93,9 +94,9 @@ impl<'tcx> InferCtxt<'tcx> { ty::TraitRef::new(self.tcx, trait_def_id, [ty]), )) { Ok(Some(selection)) => { - let mut fulfill_cx = >::new(self); - fulfill_cx.register_predicate_obligations(self, selection.nested_obligations()); - Some(fulfill_cx.select_all_or_error(self)) + let ocx = ObligationCtxt::new(self); + ocx.register_obligations(selection.nested_obligations()); + Some(ocx.select_all_or_error()) } Ok(None) | Err(_) => None, } diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 7c6dd4d3febc..97de25295b81 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -14,7 +14,6 @@ use rustc_ast_ir::visit::VisitorResult; use rustc_infer::infer::resolve::EagerResolver; use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; -use rustc_infer::traits::{TraitEngine, TraitEngineExt}; use rustc_macros::extension; use rustc_middle::infer::unify_key::ConstVariableOrigin; use rustc_middle::traits::query::NoSolution; @@ -26,9 +25,9 @@ use rustc_middle::ty::TypeFoldable; use rustc_span::{Span, DUMMY_SP}; use crate::solve::eval_ctxt::canonical; -use crate::solve::FulfillmentCtxt; use crate::solve::{EvalCtxt, GoalEvaluationKind, GoalSource}; use crate::solve::{GenerateProofTree, InferCtxtEvalExt}; +use crate::traits::ObligationCtxt; pub struct InspectConfig { pub max_depth: usize, @@ -74,14 +73,13 @@ impl<'tcx> NormalizesToTermHack<'tcx> { .eq(DefineOpaqueTypes::Yes, self.term, self.unconstrained_term) .map_err(|_| NoSolution) .and_then(|InferOk { value: (), obligations }| { - let mut fulfill_cx = FulfillmentCtxt::new(infcx); - fulfill_cx.register_predicate_obligations(infcx, obligations); - if fulfill_cx.select_where_possible(infcx).is_empty() { - if fulfill_cx.pending_obligations().is_empty() { - Ok(Certainty::Yes) - } else { - Ok(Certainty::AMBIGUOUS) - } + let ocx = ObligationCtxt::new(infcx); + ocx.register_obligations(obligations); + let errors = ocx.select_all_or_error(); + if errors.is_empty() { + Ok(Certainty::Yes) + } else if errors.iter().all(|e| !e.is_true_error()) { + Ok(Certainty::AMBIGUOUS) } else { Err(NoSolution) } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 86e7c42376aa..59725ce9de09 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -6,12 +6,9 @@ use crate::infer::outlives::env::OutlivesEnvironment; use crate::infer::InferOk; -use crate::regions::InferCtxtRegionExt; use crate::solve::inspect::{InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor}; -use crate::solve::{deeply_normalize_for_diagnostics, inspect, FulfillmentCtxt}; -use crate::traits::engine::TraitEngineExt as _; +use crate::solve::{deeply_normalize_for_diagnostics, inspect}; use crate::traits::select::IntercrateAmbiguityCause; -use crate::traits::structural_normalize::StructurallyNormalizeExt; use crate::traits::NormalizeExt; use crate::traits::SkipLeakCheck; use crate::traits::{ @@ -22,7 +19,7 @@ use rustc_errors::{Diag, EmissionGuarantee}; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; -use rustc_infer::traits::{util, FulfillmentErrorCode, TraitEngine, TraitEngineExt}; +use rustc_infer::traits::{util, FulfillmentErrorCode}; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal}; use rustc_middle::traits::specialization_graph::OverlapMode; @@ -35,6 +32,7 @@ use std::fmt::Debug; use std::ops::ControlFlow; use super::error_reporting::suggest_new_overflow_limit; +use super::ObligationCtxt; /// Whether we do the orphan check relative to this crate or to some remote crate. #[derive(Copy, Clone, Debug)] @@ -361,23 +359,27 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>( let infcx = selcx.infcx; if infcx.next_trait_solver() { - let mut fulfill_cx = FulfillmentCtxt::new(infcx); - fulfill_cx.register_predicate_obligations(infcx, obligations.iter().cloned()); - + let ocx = ObligationCtxt::new(infcx); + ocx.register_obligations(obligations.iter().cloned()); + let errors_and_ambiguities = ocx.select_all_or_error(); // We only care about the obligations that are *definitely* true errors. // Ambiguities do not prove the disjointness of two impls. - let errors = fulfill_cx.select_where_possible(infcx); + let (errors, ambiguities): (Vec<_>, Vec<_>) = + errors_and_ambiguities.into_iter().partition(|error| error.is_true_error()); + if errors.is_empty() { - let overflow_errors = fulfill_cx.collect_remaining_errors(infcx); - let overflowing_predicates = overflow_errors - .into_iter() - .filter(|e| match e.code { - FulfillmentErrorCode::Ambiguity { overflow: Some(true) } => true, - _ => false, - }) - .map(|e| infcx.resolve_vars_if_possible(e.obligation.predicate)) - .collect(); - IntersectionHasImpossibleObligations::No { overflowing_predicates } + IntersectionHasImpossibleObligations::No { + overflowing_predicates: ambiguities + .into_iter() + .filter(|error| { + matches!( + error.code, + FulfillmentErrorCode::Ambiguity { overflow: Some(true) } + ) + }) + .map(|e| infcx.resolve_vars_if_possible(e.obligation.predicate)) + .collect(), + } } else { IntersectionHasImpossibleObligations::Yes } @@ -589,13 +591,14 @@ fn try_prove_negated_where_clause<'tcx>( // Without this, we over-eagerly register coherence ambiguity candidates when // impl candidates do exist. let ref infcx = root_infcx.fork_with_intercrate(false); - let mut fulfill_cx = FulfillmentCtxt::new(infcx); - - fulfill_cx.register_predicate_obligation( - infcx, - Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, negative_predicate), - ); - if !fulfill_cx.select_all_or_error(infcx).is_empty() { + let ocx = ObligationCtxt::new(infcx); + ocx.register_obligation(Obligation::new( + infcx.tcx, + ObligationCause::dummy(), + param_env, + negative_predicate, + )); + if !ocx.select_all_or_error().is_empty() { return false; } @@ -603,8 +606,7 @@ fn try_prove_negated_where_clause<'tcx>( // if that wasn't implemented just for LocalDefId, and we'd need to do // the normalization ourselves since this is totally fallible... let outlives_env = OutlivesEnvironment::new(param_env); - - let errors = infcx.resolve_regions(&outlives_env); + let errors = ocx.resolve_regions(&outlives_env); if !errors.is_empty() { return false; } @@ -1129,22 +1131,17 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> { result: Ok(_), } = cand.kind() { - let lazily_normalize_ty = |ty: Ty<'tcx>| { - let mut fulfill_cx = >::new(infcx); + let lazily_normalize_ty = |mut ty: Ty<'tcx>| { if matches!(ty.kind(), ty::Alias(..)) { - // FIXME(-Znext-solver=coherence): we currently don't - // normalize opaque types here, resulting in diverging behavior - // for TAITs. - match infcx - .at(&ObligationCause::dummy(), param_env) - .structurally_normalize(ty, &mut *fulfill_cx) - { - Ok(ty) => Ok(ty), - Err(_errs) => Err(()), + let ocx = ObligationCtxt::new(infcx); + ty = ocx + .structurally_normalize(&ObligationCause::dummy(), param_env, ty) + .map_err(|_| ())?; + if !ocx.select_where_possible().is_empty() { + return Err(()); } - } else { - Ok(ty) } + Ok(ty) }; infcx.probe(|_| { diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 432d51ff8f90..9eaaef1eb228 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -7,6 +7,7 @@ use crate::regions::InferCtxtRegionExt; use crate::solve::FulfillmentCtxt as NextFulfillmentCtxt; use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::NormalizeExt; +use crate::traits::StructurallyNormalizeExt; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -15,6 +16,7 @@ use rustc_infer::infer::canonical::{ Canonical, CanonicalQueryResponse, CanonicalVarValues, QueryResponse, }; use rustc_infer::infer::outlives::env::OutlivesEnvironment; +use rustc_infer::infer::RegionResolutionError; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; use rustc_infer::traits::{ FulfillmentError, Obligation, ObligationCause, PredicateObligation, TraitEngineExt as _, @@ -117,6 +119,17 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut()) } + pub fn structurally_normalize( + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + value: Ty<'tcx>, + ) -> Result, Vec>> { + self.infcx + .at(cause, param_env) + .structurally_normalize(value, &mut **self.engine.borrow_mut()) + } + pub fn eq>( &self, cause: &ObligationCause<'tcx>, @@ -182,6 +195,11 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { self.engine.borrow_mut().select_all_or_error(self.infcx) } + #[must_use] + pub fn pending_obligations(&self) -> Vec> { + self.engine.borrow().pending_obligations() + } + /// Resolves regions and reports errors. /// /// Takes ownership of the context as doing trait solving afterwards @@ -199,6 +217,18 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { } } + /// Resolves regions and reports errors. + /// + /// Takes ownership of the context as doing trait solving afterwards + /// will result in region constraints getting ignored. + #[must_use] + pub fn resolve_regions( + self, + outlives_env: &OutlivesEnvironment<'tcx>, + ) -> Vec> { + self.infcx.resolve_regions(outlives_env) + } + pub fn assumed_wf_types_and_report_errors( &self, param_env: ty::ParamEnv<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs index 5f2a89441352..87d240cf8ac7 100644 --- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs +++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs @@ -1,9 +1,10 @@ -use rustc_infer::traits::{TraitEngine, TraitEngineExt}; use rustc_macros::extension; use crate::infer::canonical::OriginalQueryValues; use crate::infer::InferCtxt; -use crate::traits::{EvaluationResult, OverflowError, PredicateObligation, SelectionContext}; +use crate::traits::{ + EvaluationResult, ObligationCtxt, OverflowError, PredicateObligation, SelectionContext, +}; #[extension(pub trait InferCtxtExt<'tcx>)] impl<'tcx> InferCtxt<'tcx> { @@ -67,21 +68,22 @@ impl<'tcx> InferCtxt<'tcx> { if self.next_trait_solver() { self.probe(|snapshot| { - let mut fulfill_cx = crate::solve::FulfillmentCtxt::new(self); - fulfill_cx.register_predicate_obligation(self, obligation.clone()); - // True errors - // FIXME(-Znext-solver): Overflows are reported as ambig here, is that OK? - if !fulfill_cx.select_where_possible(self).is_empty() { - Ok(EvaluationResult::EvaluatedToErr) - } else if !fulfill_cx.select_all_or_error(self).is_empty() { - Ok(EvaluationResult::EvaluatedToAmbig) - } else if self.opaque_types_added_in_snapshot(snapshot) { - Ok(EvaluationResult::EvaluatedToOkModuloOpaqueTypes) - } else if self.region_constraints_added_in_snapshot(snapshot) { - Ok(EvaluationResult::EvaluatedToOkModuloRegions) - } else { - Ok(EvaluationResult::EvaluatedToOk) + let ocx = ObligationCtxt::new(self); + ocx.register_obligation(obligation.clone()); + let mut result = EvaluationResult::EvaluatedToOk; + for error in ocx.select_all_or_error() { + if error.is_true_error() { + return Ok(EvaluationResult::EvaluatedToErr); + } else { + result = result.max(EvaluationResult::EvaluatedToAmbig); + } } + if self.opaque_types_added_in_snapshot(snapshot) { + result = result.max(EvaluationResult::EvaluatedToOkModuloOpaqueTypes); + } else if self.region_constraints_added_in_snapshot(snapshot) { + result = result.max(EvaluationResult::EvaluatedToOkModuloRegions); + } + Ok(result) }) } else { assert!(!self.intercrate); diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index 51f38964415b..b96b1b67a740 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -4,14 +4,13 @@ // general routines. use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::traits::{FulfillmentErrorCode, TraitEngineExt as _}; +use rustc_infer::traits::FulfillmentErrorCode; use rustc_middle::bug; use rustc_middle::traits::CodegenObligationError; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::{ - ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine, TraitEngineExt, - Unimplemented, + ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext, Unimplemented, }; use tracing::debug; @@ -51,15 +50,15 @@ pub fn codegen_select_candidate<'tcx>( // Currently, we use a fulfillment context to completely resolve // all nested obligations. This is because they can inform the // inference of the impl's type parameters. - let mut fulfill_cx = >::new(&infcx); - let impl_source = selection.map(|predicate| { - fulfill_cx.register_predicate_obligation(&infcx, predicate); + let ocx = ObligationCtxt::new(&infcx); + let impl_source = selection.map(|obligation| { + ocx.register_obligation(obligation); }); // In principle, we only need to do this so long as `impl_source` // contains unbound type parameters. It could be a slight // optimization to stop iterating early. - let errors = fulfill_cx.select_all_or_error(&infcx); + let errors = ocx.select_all_or_error(); if !errors.is_empty() { // `rustc_monomorphize::collector` assumes there are no type errors. // Cycle errors are the only post-monomorphization errors possible; emit them now so From 92861517aa7b97aaaeb444fa898dec3ede29f2aa Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 1 May 2024 22:39:49 -0400 Subject: [PATCH 271/279] Take ocx by move for pending obligations --- compiler/rustc_hir_analysis/src/autoderef.rs | 2 +- compiler/rustc_hir_typeck/src/coercion.rs | 4 ++-- compiler/rustc_trait_selection/src/traits/engine.rs | 9 ++++++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index 4e85045ef495..f101c595bdf3 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -188,7 +188,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { return None; } - Some((normalized_ty, ocx.pending_obligations())) + Some((normalized_ty, ocx.into_pending_obligations())) } /// Returns the final type we ended up with, which may be an inference diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index e5514fecfbee..076c1936ded8 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -165,7 +165,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let ocx = ObligationCtxt::new(self); ocx.register_obligations(obligations); if ocx.select_where_possible().is_empty() { - Ok(InferOk { value, obligations: ocx.pending_obligations() }) + Ok(InferOk { value, obligations: ocx.into_pending_obligations() }) } else { Err(TypeError::Mismatch) } @@ -633,7 +633,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { if !ocx.select_where_possible().is_empty() { return Err(TypeError::Mismatch); } - coercion.obligations.extend(ocx.pending_obligations()); + coercion.obligations.extend(ocx.into_pending_obligations()); continue; } _ => { diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 9eaaef1eb228..551c8e7702ef 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -195,8 +195,15 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { self.engine.borrow_mut().select_all_or_error(self.infcx) } + /// Returns the not-yet-processed and stalled obligations from the + /// `ObligationCtxt`. + /// + /// Takes ownership of the context as doing operations such as + /// [`ObligationCtxt::eq`] afterwards will result in other obligations + /// getting ignored. You can make a new `ObligationCtxt` if this + /// needs to be done in a loop, for example. #[must_use] - pub fn pending_obligations(&self) -> Vec> { + pub fn into_pending_obligations(self) -> Vec> { self.engine.borrow().pending_obligations() } From 2c4214e0a00287be39c2b8d5331b4fa4f88b1390 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 2 May 2024 12:04:20 +0200 Subject: [PATCH 272/279] run-make: port stdin-rustc to Rust-based rmake.rs --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/stdin-non-utf8/Makefile | 6 ----- tests/run-make/stdin-non-utf8/non-utf8 | 1 - tests/run-make/stdin-rustc/rmake.rs | 26 +++++++++++++++++++ 4 files changed, 26 insertions(+), 8 deletions(-) delete mode 100644 tests/run-make/stdin-non-utf8/Makefile delete mode 100644 tests/run-make/stdin-non-utf8/non-utf8 create mode 100644 tests/run-make/stdin-rustc/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 69c6dda4b19c..4b79b910ec39 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -288,7 +288,6 @@ run-make/static-unwinding/Makefile run-make/staticlib-blank-lib/Makefile run-make/staticlib-dylib-linkage/Makefile run-make/std-core-cycle/Makefile -run-make/stdin-non-utf8/Makefile run-make/suspicious-library/Makefile run-make/symbol-mangling-hashed/Makefile run-make/symbol-visibility/Makefile diff --git a/tests/run-make/stdin-non-utf8/Makefile b/tests/run-make/stdin-non-utf8/Makefile deleted file mode 100644 index 709d4cf14089..000000000000 --- a/tests/run-make/stdin-non-utf8/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -include ../tools.mk - -all: - cp non-utf8 $(TMPDIR)/non-utf.rs - cat $(TMPDIR)/non-utf.rs | $(RUSTC) - 2>&1 \ - | $(CGREP) "error: couldn't read from stdin, as it did not contain valid UTF-8" diff --git a/tests/run-make/stdin-non-utf8/non-utf8 b/tests/run-make/stdin-non-utf8/non-utf8 deleted file mode 100644 index bc87051a8529..000000000000 --- a/tests/run-make/stdin-non-utf8/non-utf8 +++ /dev/null @@ -1 +0,0 @@ - diff --git a/tests/run-make/stdin-rustc/rmake.rs b/tests/run-make/stdin-rustc/rmake.rs new file mode 100644 index 000000000000..c07a6df4d84a --- /dev/null +++ b/tests/run-make/stdin-rustc/rmake.rs @@ -0,0 +1,26 @@ +//! This test checks rustc `-` (stdin) support + +use run_make_support::{is_windows, rustc, tmp_dir}; + +const HELLO_WORLD: &str = r#" +fn main() { + println!("Hello world!"); +} +"#; + +const NOT_UTF8: &[u8] = &[0xff, 0xff, 0xff]; + +fn main() { + let out_dir = tmp_dir(); + + // echo $HELLO_WORLD | rustc - + rustc().arg("-").stdin(HELLO_WORLD).run(); + assert!( + out_dir.join(if !is_windows() { "rust_out" } else { "rust_out.exe" }).try_exists().unwrap() + ); + + // echo $NOT_UTF8 | rustc - + let output = rustc().arg("-").stdin(NOT_UTF8).run_fail(); + let stderr = String::from_utf8(output.stderr).unwrap(); + assert!(stderr.contains("error: couldn't read from stdin, as it did not contain valid UTF-8")); +} From bdf1eae36079e21f449e8f3859ebfa584b9ffbd0 Mon Sep 17 00:00:00 2001 From: Andrea Ciliberti Date: Fri, 3 May 2024 10:09:28 +0200 Subject: [PATCH 273/279] Horizon OS: dirfd unavailable --- library/std/src/sys/pal/unix/fs.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index d2006dfc12b5..32cdd13fbebd 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -860,6 +860,7 @@ impl Drop for Dir { target_os = "hurd", target_os = "espidf", target_os = "fuchsia", + target_os = "horizon", )))] { let fd = unsafe { libc::dirfd(self.0) }; From 3d1062c1a48a3a2c047e65191cc875491f2349b3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 2 May 2024 12:36:56 +0200 Subject: [PATCH 274/279] Allow to negate ignored files --- src/bootstrap/src/core/build_steps/format.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index 9fc65a0a73a1..d9dc34c01370 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -115,7 +115,11 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { let rustfmt_config: RustfmtConfig = t!(toml::from_str(&rustfmt_config)); let mut fmt_override = ignore::overrides::OverrideBuilder::new(&build.src); for ignore in rustfmt_config.ignore { - fmt_override.add(&format!("!{ignore}")).expect(&ignore); + if let Some(ignore) = ignore.strip_prefix('!') { + fmt_override.add(ignore).expect(ignore); + } else { + fmt_override.add(&format!("!{ignore}")).expect(&ignore); + } } let git_available = match Command::new("git") .arg("--version") From 8f47f9773d4cdee3f611b7d1b0865cbf8e39a57b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 2 May 2024 12:37:13 +0200 Subject: [PATCH 275/279] Allow `fmt` to run on `rmake.rs` test files --- rustfmt.toml | 2 +- tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs | 8 ++--- tests/run-make/compiler-builtins/rmake.rs | 32 +++++++++---------- tests/run-make/exit-code/rmake.rs | 30 ++++------------- .../print-native-static-libs/rmake.rs | 16 ++++------ tests/run-make/print-to-output/rmake.rs | 6 +--- .../wasm-custom-sections-opt/rmake.rs | 2 +- .../run-make/wasm-export-all-symbols/rmake.rs | 2 +- tests/run-make/wasm-import-module/rmake.rs | 9 ++---- 9 files changed, 38 insertions(+), 69 deletions(-) diff --git a/rustfmt.toml b/rustfmt.toml index 0b0674af8b4a..67219b15d203 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -13,7 +13,7 @@ ignore = [ # tests for now are not formatted, as they are sometimes pretty-printing constrained # (and generally rustfmt can move around comments in UI-testing incompatible ways) - "/tests/", + "!/tests/run-make/*/rmake.rs", # do not format submodules # FIXME: sync submodule list with tidy/bootstrap/etc diff --git a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs index fe0ceaf6b043..4b7ce4e57d57 100644 --- a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs +++ b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs @@ -5,7 +5,7 @@ use std::path::PathBuf; -use run_make_support::{rustc, aux_build}; +use run_make_support::{aux_build, rustc}; fn main() { aux_build().input("stable.rs").emit("metadata").run(); @@ -13,11 +13,7 @@ fn main() { let mut stable_path = PathBuf::from(env!("TMPDIR")); stable_path.push("libstable.rmeta"); - let output = rustc() - .input("main.rs") - .emit("metadata") - .extern_("stable", &stable_path) - .output(); + let output = rustc().input("main.rs").emit("metadata").extern_("stable", &stable_path).output(); let stderr = String::from_utf8_lossy(&output.stderr); let version = include_str!(concat!(env!("S"), "/src/version")); diff --git a/tests/run-make/compiler-builtins/rmake.rs b/tests/run-make/compiler-builtins/rmake.rs index 178478484599..f5da50ebb043 100644 --- a/tests/run-make/compiler-builtins/rmake.rs +++ b/tests/run-make/compiler-builtins/rmake.rs @@ -49,22 +49,22 @@ fn main() { let bootstrap_cargo = std::env::var("BOOTSTRAP_CARGO").unwrap(); let mut cmd = std::process::Command::new(bootstrap_cargo); cmd.args([ - "build", - "--manifest-path", - manifest_path.to_str().unwrap(), - "-Zbuild-std=core", - "--target", - &target, - ]) - .env_clear() - .env("PATH", path) - .env("RUSTC", rustc) - .env("RUSTFLAGS", "-Copt-level=0 -Cdebug-assertions=yes") - .env("CARGO_TARGET_DIR", &target_dir) - .env("RUSTC_BOOTSTRAP", "1") - // Visual Studio 2022 requires that the LIB env var be set so it can - // find the Windows SDK. - .env("LIB", std::env::var("LIB").unwrap_or_default()); + "build", + "--manifest-path", + manifest_path.to_str().unwrap(), + "-Zbuild-std=core", + "--target", + &target, + ]) + .env_clear() + .env("PATH", path) + .env("RUSTC", rustc) + .env("RUSTFLAGS", "-Copt-level=0 -Cdebug-assertions=yes") + .env("CARGO_TARGET_DIR", &target_dir) + .env("RUSTC_BOOTSTRAP", "1") + // Visual Studio 2022 requires that the LIB env var be set so it can + // find the Windows SDK. + .env("LIB", std::env::var("LIB").unwrap_or_default()); set_host_rpath(&mut cmd); let status = cmd.status().unwrap(); diff --git a/tests/run-make/exit-code/rmake.rs b/tests/run-make/exit-code/rmake.rs index f4ceabe126cb..b1143153d0af 100644 --- a/tests/run-make/exit-code/rmake.rs +++ b/tests/run-make/exit-code/rmake.rs @@ -3,17 +3,11 @@ use run_make_support::{rustc, rustdoc, tmp_dir}; fn main() { - rustc() - .arg("success.rs") - .run(); + rustc().arg("success.rs").run(); - rustc() - .arg("--invalid-arg-foo") - .run_fail_assert_exit_code(1); + rustc().arg("--invalid-arg-foo").run_fail_assert_exit_code(1); - rustc() - .arg("compile-error.rs") - .run_fail_assert_exit_code(1); + rustc().arg("compile-error.rs").run_fail_assert_exit_code(1); rustc() .env("RUSTC_ICE", "0") @@ -21,21 +15,11 @@ fn main() { .arg("compile-error.rs") .run_fail_assert_exit_code(101); - rustdoc() - .arg("success.rs") - .arg("-o") - .arg(tmp_dir().join("exit-code")) - .run(); + rustdoc().arg("success.rs").arg("-o").arg(tmp_dir().join("exit-code")).run(); - rustdoc() - .arg("--invalid-arg-foo") - .run_fail_assert_exit_code(1); + rustdoc().arg("--invalid-arg-foo").run_fail_assert_exit_code(1); - rustdoc() - .arg("compile-error.rs") - .run_fail_assert_exit_code(1); + rustdoc().arg("compile-error.rs").run_fail_assert_exit_code(1); - rustdoc() - .arg("lint-failure.rs") - .run_fail_assert_exit_code(1); + rustdoc().arg("lint-failure.rs").run_fail_assert_exit_code(1); } diff --git a/tests/run-make/print-native-static-libs/rmake.rs b/tests/run-make/print-native-static-libs/rmake.rs index 5249920cc60e..edb85d568c67 100644 --- a/tests/run-make/print-native-static-libs/rmake.rs +++ b/tests/run-make/print-native-static-libs/rmake.rs @@ -14,15 +14,11 @@ use std::io::BufRead; -use run_make_support::{rustc, is_msvc}; +use run_make_support::{is_msvc, rustc}; fn main() { // build supporting crate - rustc() - .input("bar.rs") - .crate_type("rlib") - .arg("-lbar_cli") - .run(); + rustc().input("bar.rs").crate_type("rlib").arg("-lbar_cli").run(); // build main crate as staticlib let output = rustc() @@ -37,7 +33,9 @@ fn main() { for l in output.stderr.lines() { let l = l.expect("utf-8 string"); - let Some(args) = l.strip_prefix("note: native-static-libs:") else { continue; }; + let Some(args) = l.strip_prefix("note: native-static-libs:") else { + continue; + }; assert!(!found_note); found_note = true; @@ -53,11 +51,11 @@ fn main() { ); let found = $args.contains(&&*lib); assert!(found, "unable to find lib `{}` in those linker args: {:?}", lib, $args); - }} + }}; } assert_contains_lib!("glib-2.0" in args); // in bar.rs - assert_contains_lib!("systemd" in args); // in foo.rs + assert_contains_lib!("systemd" in args); // in foo.rs assert_contains_lib!("bar_cli" in args); assert_contains_lib!("foo_cli" in args); diff --git a/tests/run-make/print-to-output/rmake.rs b/tests/run-make/print-to-output/rmake.rs index f710d0dc3c9b..1763cd378d2d 100644 --- a/tests/run-make/print-to-output/rmake.rs +++ b/tests/run-make/print-to-output/rmake.rs @@ -13,11 +13,7 @@ struct Option<'a> { fn main() { // Printed from CodegenBackend trait impl in rustc_codegen_llvm/src/lib.rs - check(Option { - target: &target(), - option: "relocation-models", - includes: &["dynamic-no-pic"], - }); + check(Option { target: &target(), option: "relocation-models", includes: &["dynamic-no-pic"] }); // Printed by compiler/rustc_codegen_llvm/src/llvm_util.rs check(Option { diff --git a/tests/run-make/wasm-custom-sections-opt/rmake.rs b/tests/run-make/wasm-custom-sections-opt/rmake.rs index 24570d8baf5a..50916b1bf815 100644 --- a/tests/run-make/wasm-custom-sections-opt/rmake.rs +++ b/tests/run-make/wasm-custom-sections-opt/rmake.rs @@ -1,6 +1,6 @@ //@ only-wasm32-wasip1 -use run_make_support::{tmp_dir, wasmparser, rustc}; +use run_make_support::{rustc, tmp_dir, wasmparser}; use std::collections::HashMap; use std::path::Path; diff --git a/tests/run-make/wasm-export-all-symbols/rmake.rs b/tests/run-make/wasm-export-all-symbols/rmake.rs index 50c99d027d5a..f4c51bc4ab41 100644 --- a/tests/run-make/wasm-export-all-symbols/rmake.rs +++ b/tests/run-make/wasm-export-all-symbols/rmake.rs @@ -1,6 +1,6 @@ //@ only-wasm32-wasip1 -use run_make_support::{tmp_dir, wasmparser, rustc}; +use run_make_support::{rustc, tmp_dir, wasmparser}; use std::collections::HashMap; use std::path::Path; use wasmparser::ExternalKind::*; diff --git a/tests/run-make/wasm-import-module/rmake.rs b/tests/run-make/wasm-import-module/rmake.rs index 333d0df4653f..6eed229e9078 100644 --- a/tests/run-make/wasm-import-module/rmake.rs +++ b/tests/run-make/wasm-import-module/rmake.rs @@ -1,17 +1,12 @@ //@ only-wasm32-wasip1 -use run_make_support::{tmp_dir, wasmparser, rustc}; +use run_make_support::{rustc, tmp_dir, wasmparser}; use std::collections::HashMap; use wasmparser::TypeRef::Func; fn main() { rustc().input("foo.rs").target("wasm32-wasip1").run(); - rustc() - .input("bar.rs") - .target("wasm32-wasip1") - .arg("-Clto") - .opt() - .run(); + rustc().input("bar.rs").target("wasm32-wasip1").arg("-Clto").opt().run(); let file = std::fs::read(&tmp_dir().join("bar.wasm")).unwrap(); From 47e2cc2ea1dd842b8d67fde17c6d37622ec67a40 Mon Sep 17 00:00:00 2001 From: Strophox Date: Mon, 22 Apr 2024 03:57:01 +0200 Subject: [PATCH 276/279] generalize adjust_from_tcx --- compiler/rustc_middle/src/mir/interpret/allocation.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 9cc5c6a2ee94..0828e2858f7d 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -346,10 +346,10 @@ impl Allocation { } } -impl Allocation { +impl Allocation { /// Adjust allocation from the ones in `tcx` to a custom Machine instance - /// with a different `Provenance` and `Extra` type. - pub fn adjust_from_tcx( + /// with a different `Provenance`, `Extra` and `Byte` type. + pub fn adjust_from_tcx( self, cx: &impl HasDataLayout, extra: Extra, @@ -371,7 +371,7 @@ impl Allocation { } // Create allocation. Ok(Allocation { - bytes, + bytes: AllocBytes::from_bytes(Cow::from(&*bytes), self.align), provenance: ProvenanceMap::from_presorted_ptrs(new_provenance), init_mask: self.init_mask, align: self.align, From 235770c851513dd61d2af92d8b4b969385c55f9a Mon Sep 17 00:00:00 2001 From: Strophox Date: Sun, 28 Apr 2024 21:40:21 +0200 Subject: [PATCH 277/279] Cow::from(&*...) changed to Cow::Owned(Vec::from(...)) --- compiler/rustc_middle/src/mir/interpret/allocation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 0828e2858f7d..8b8101f3d1f5 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -371,7 +371,7 @@ impl Allocation { } // Create allocation. Ok(Allocation { - bytes: AllocBytes::from_bytes(Cow::from(&*bytes), self.align), + bytes: AllocBytes::from_bytes(Cow::Owned(Vec::from(bytes)), self.align), provenance: ProvenanceMap::from_presorted_ptrs(new_provenance), init_mask: self.init_mask, align: self.align, From 38181cba79e8a711e409ca04b9780ef6243aa4fe Mon Sep 17 00:00:00 2001 From: Strophox Date: Fri, 3 May 2024 14:56:42 +0200 Subject: [PATCH 278/279] remove trait bounds on AllocBytes --- compiler/rustc_middle/src/mir/interpret/allocation.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 8b8101f3d1f5..791e87735f40 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -29,9 +29,7 @@ use provenance_map::*; pub use init_mask::{InitChunk, InitChunkIter}; /// Functionality required for the bytes of an `Allocation`. -pub trait AllocBytes: - Clone + fmt::Debug + Eq + PartialEq + Hash + Deref + DerefMut -{ +pub trait AllocBytes: Clone + fmt::Debug + Deref + DerefMut { /// Create an `AllocBytes` from a slice of `u8`. fn from_bytes<'a>(slice: impl Into>, _align: Align) -> Self; From f43e3e2023f28d7e7a9f870612c6f2ef867a2acb Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 4 May 2024 12:37:30 +0200 Subject: [PATCH 279/279] Fix ignored tests for formatting --- rustfmt.toml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rustfmt.toml b/rustfmt.toml index 67219b15d203..850d01ea7cb8 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -13,6 +13,12 @@ ignore = [ # tests for now are not formatted, as they are sometimes pretty-printing constrained # (and generally rustfmt can move around comments in UI-testing incompatible ways) + "/tests/*", + + # but we still want to format rmake.rs files in tests/run-make/ so we need to do this + # dance to avoid the parent directory from being excluded + "!/tests/run-make/", + "/tests/run-make/*/*.rs", "!/tests/run-make/*/rmake.rs", # do not format submodules