From b0a89441208e56f85b5c51eccde89275f667f787 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Thu, 1 Aug 2024 00:57:38 +0300 Subject: rustc_errors: enforce OUTPUT_REPLACEMENTS is sorted with a compile-time assertion --- compiler/rustc_errors/src/emitter.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index d673646ace4..0e9c7ef5fb3 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2564,9 +2564,7 @@ fn num_decimal_digits(num: usize) -> usize { // We replace some characters so the CLI output is always consistent and underlines aligned. // Keep the following list in sync with `rustc_span::char_width`. -// ATTENTION: keep lexicografically sorted so that the binary search will work const OUTPUT_REPLACEMENTS: &[(char, &str)] = &[ - // tidy-alphabetical-start // In terminals without Unicode support the following will be garbled, but in *all* terminals // the underlying codepoint will be as well. We could gate this replacement behind a "unicode // support" gate. @@ -2579,7 +2577,7 @@ const OUTPUT_REPLACEMENTS: &[(char, &str)] = &[ ('\u{0006}', "␆"), ('\u{0007}', "␇"), ('\u{0008}', "␈"), - ('\u{0009}', " "), // We do our own tab replacement + ('\t', " "), // We do our own tab replacement ('\u{000b}', "␋"), ('\u{000c}', "␌"), ('\u{000d}', "␍"), @@ -2612,10 +2610,20 @@ const OUTPUT_REPLACEMENTS: &[(char, &str)] = &[ ('\u{2067}', "�"), ('\u{2068}', "�"), ('\u{2069}', "�"), - // tidy-alphabetical-end ]; fn normalize_whitespace(s: &str) -> String { + const { + let mut i = 1; + while i < OUTPUT_REPLACEMENTS.len() { + assert!( + OUTPUT_REPLACEMENTS[i - 1].0 < OUTPUT_REPLACEMENTS[i].0, + "The OUTPUT_REPLACEMENTS array must be sorted (for binary search to work) \ + and must contain no duplicate entries" + ); + i += 1; + } + } // Scan the input string for a character in the ordered table above. If it's present, replace // it with it's alternative string (it can be more than 1 char!). Otherwise, retain the input // char. At the end, allocate all chars into a string in one operation. -- cgit 1.4.1-3-g733a5 From 15982b2fcae0fba61816dbd31617bc6604e36af5 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Thu, 1 Aug 2024 01:02:25 +0300 Subject: rustc_errors: fix inaccurate comment --- compiler/rustc_errors/src/emitter.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 0e9c7ef5fb3..ef9194022b5 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2624,9 +2624,9 @@ fn normalize_whitespace(s: &str) -> String { i += 1; } } - // Scan the input string for a character in the ordered table above. If it's present, replace - // it with it's alternative string (it can be more than 1 char!). Otherwise, retain the input - // char. At the end, allocate all chars into a string in one operation. + // Scan the input string for a character in the ordered table above. + // If it's present, replace it with its alternative string (it can be more than 1 char!). + // Otherwise, retain the input char. s.chars().fold(String::with_capacity(s.len()), |mut s, c| { match OUTPUT_REPLACEMENTS.binary_search_by_key(&c, |(k, _)| *k) { Ok(i) => s.push_str(OUTPUT_REPLACEMENTS[i].1), -- cgit 1.4.1-3-g733a5 From c4c518d2d496774ecc7a368e826480d1928ed1ab Mon Sep 17 00:00:00 2001 From: León Orell Valerian Liehr Date: Wed, 7 Aug 2024 12:41:49 +0200 Subject: Use more slice patterns inside the compiler --- compiler/rustc_ast/src/ast.rs | 12 +++-- compiler/rustc_ast_lowering/src/delegation.rs | 4 +- compiler/rustc_ast_pretty/src/pprust/state.rs | 4 +- compiler/rustc_ast_pretty/src/pprust/state/item.rs | 4 +- compiler/rustc_attr/src/builtin.rs | 14 +++--- .../src/diagnostics/outlives_suggestion.rs | 4 +- compiler/rustc_builtin_macros/src/asm.rs | 7 ++- .../src/deriving/generic/mod.rs | 8 ++-- compiler/rustc_builtin_macros/src/format.rs | 8 ++-- .../src/transitive_relation.rs | 6 +-- compiler/rustc_driver_impl/src/lib.rs | 55 ++++++++++------------ compiler/rustc_errors/src/emitter.rs | 29 ++++++------ compiler/rustc_errors/src/lib.rs | 10 ++-- compiler/rustc_expand/src/base.rs | 8 ++-- compiler/rustc_hir_typeck/src/expr.rs | 11 +---- compiler/rustc_hir_typeck/src/method/confirm.rs | 8 ++-- compiler/rustc_hir_typeck/src/method/suggest.rs | 43 +++++++++-------- compiler/rustc_lint/src/nonstandard_style.rs | 4 +- compiler/rustc_lint/src/types.rs | 9 ++-- compiler/rustc_lint/src/unused.rs | 10 ++-- .../src/thir/pattern/check_match.rs | 6 ++- compiler/rustc_mir_transform/src/coverage/graph.rs | 4 +- .../src/early_otherwise_branch.rs | 6 +-- compiler/rustc_mir_transform/src/instsimplify.rs | 6 +-- compiler/rustc_mir_transform/src/validate.rs | 14 +++--- compiler/rustc_parse/src/parser/expr.rs | 6 +-- compiler/rustc_parse/src/parser/item.rs | 5 +- compiler/rustc_parse/src/parser/path.rs | 3 +- compiler/rustc_parse/src/parser/stmt.rs | 6 +-- compiler/rustc_passes/src/check_attr.rs | 4 +- compiler/rustc_passes/src/debugger_visualizer.rs | 4 +- compiler/rustc_query_system/src/dep_graph/debug.rs | 11 ++--- compiler/rustc_resolve/src/late.rs | 20 ++++---- compiler/rustc_resolve/src/late/diagnostics.rs | 13 +++-- compiler/rustc_resolve/src/macros.rs | 10 ++-- compiler/rustc_session/src/options.rs | 13 ++--- compiler/rustc_target/src/spec/mod.rs | 9 ++-- .../error_reporting/traits/fulfillment_errors.rs | 3 +- .../src/error_reporting/traits/on_unimplemented.rs | 8 ++-- .../src/error_reporting/traits/suggestions.rs | 3 +- 40 files changed, 191 insertions(+), 221 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index fc1af3fc3dd..a44ed828504 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -585,7 +585,9 @@ impl Pat { } // A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array, // when `P` can be reparsed as a type `T`. - PatKind::Slice(pats) if pats.len() == 1 => pats[0].to_ty().map(TyKind::Slice)?, + PatKind::Slice(pats) if let [pat] = pats.as_slice() => { + pat.to_ty().map(TyKind::Slice)? + } // A tuple pattern `(P0, .., Pn)` can be reparsed as `(T0, .., Tn)` // assuming `T0` to `Tn` are all syntactically valid as types. PatKind::Tuple(pats) => { @@ -1187,8 +1189,8 @@ impl Expr { /// Does not ensure that the path resolves to a const param, the caller should check this. pub fn is_potential_trivial_const_arg(&self) -> bool { let this = if let ExprKind::Block(block, None) = &self.kind - && block.stmts.len() == 1 - && let StmtKind::Expr(expr) = &block.stmts[0].kind + && let [stmt] = block.stmts.as_slice() + && let StmtKind::Expr(expr) = &stmt.kind { expr } else { @@ -1248,7 +1250,9 @@ impl Expr { expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))? } - ExprKind::Array(exprs) if exprs.len() == 1 => exprs[0].to_ty().map(TyKind::Slice)?, + ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => { + expr.to_ty().map(TyKind::Slice)? + } ExprKind::Tup(exprs) => { let tys = exprs.iter().map(|expr| expr.to_ty()).collect::>>()?; diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 6e8ff72cf87..300bfa101c6 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -275,8 +275,8 @@ impl<'hir> LoweringContext<'_, 'hir> { // FIXME(fn_delegation): Alternatives for target expression lowering: // https://github.com/rust-lang/rfcs/pull/3530#issuecomment-2197170600. fn lower_target_expr(&mut self, block: &Block) -> hir::Expr<'hir> { - if block.stmts.len() == 1 - && let StmtKind::Expr(expr) = &block.stmts[0].kind + if let [stmt] = block.stmts.as_slice() + && let StmtKind::Expr(expr) = &stmt.kind { return self.lower_expr_mut(expr); } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index ee4514758c2..c7ff39d23ed 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -502,8 +502,8 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere if !self.is_beginning_of_line() { self.word(" "); } - if cmnt.lines.len() == 1 { - self.word(cmnt.lines[0].clone()); + if let [line] = cmnt.lines.as_slice() { + self.word(line.clone()); self.hardbreak() } else { self.visual_align(); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 56204d8835a..85a0b3b2022 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -783,8 +783,8 @@ impl<'a> State<'a> { } if items.is_empty() { self.word("{}"); - } else if items.len() == 1 { - self.print_use_tree(&items[0].0); + } else if let [(item, _)] = items.as_slice() { + self.print_use_tree(item); } else { self.cbox(INDENT_UNIT); self.word("{"); diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 12a19ae5c3d..cf86a6942da 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -665,12 +665,12 @@ pub fn eval_condition( res & eval_condition(mi.meta_item().unwrap(), sess, features, eval) }), sym::not => { - if mis.len() != 1 { + let [mi] = mis.as_slice() else { dcx.emit_err(session_diagnostics::ExpectedOneCfgPattern { span: cfg.span }); return false; - } + }; - !eval_condition(mis[0].meta_item().unwrap(), sess, features, eval) + !eval_condition(mi.meta_item().unwrap(), sess, features, eval) } sym::target => { if let Some(features) = features @@ -1051,10 +1051,10 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { MetaItemKind::List(nested_items) => { if meta_item.has_name(sym::align) { recognised = true; - if nested_items.len() == 1 { + if let [nested_item] = nested_items.as_slice() { sess.dcx().emit_err( session_diagnostics::IncorrectReprFormatExpectInteger { - span: nested_items[0].span(), + span: nested_item.span(), }, ); } else { @@ -1066,10 +1066,10 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { } } else if meta_item.has_name(sym::packed) { recognised = true; - if nested_items.len() == 1 { + if let [nested_item] = nested_items.as_slice() { sess.dcx().emit_err( session_diagnostics::IncorrectReprFormatPackedExpectInteger { - span: nested_items[0].span(), + span: nested_item.span(), }, ); } else { diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs index 9356c24d018..de0df347429 100644 --- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs +++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs @@ -206,8 +206,8 @@ impl OutlivesSuggestionBuilder { // If there is exactly one suggestable constraints, then just suggest it. Otherwise, emit a // list of diagnostics. - let mut diag = if suggested.len() == 1 { - mbcx.dcx().struct_help(match suggested.last().unwrap() { + let mut diag = if let [constraint] = suggested.as_slice() { + mbcx.dcx().struct_help(match constraint { SuggestedConstraint::Outlives(a, bs) => { let bs: SmallVec<[String; 2]> = bs.iter().map(|r| r.to_string()).collect(); format!("add bound `{a}: {}`", bs.join(" + ")) diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 17439dd3e3e..ed54c0c8662 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -745,10 +745,9 @@ fn expand_preparsed_asm( unused_operands.push((args.operands[idx].1, msg)); } } - match unused_operands.len() { - 0 => {} - 1 => { - let (sp, msg) = unused_operands.into_iter().next().unwrap(); + match unused_operands[..] { + [] => {} + [(sp, msg)] => { ecx.dcx() .struct_span_err(sp, msg) .with_span_label(sp, msg) diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index c8ab8ed681c..c90a9164886 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -378,8 +378,8 @@ impl BlockOrExpr { None => cx.expr_block(cx.block(span, ThinVec::new())), Some(expr) => expr, } - } else if self.0.len() == 1 - && let ast::StmtKind::Expr(expr) = &self.0[0].kind + } else if let [stmt] = self.0.as_slice() + && let ast::StmtKind::Expr(expr) = &stmt.kind && self.1.is_none() { // There's only a single statement expression. Pull it out. @@ -1273,7 +1273,7 @@ impl<'a> MethodDef<'a> { } FieldlessVariantsStrategy::Default => (), } - } else if variants.len() == 1 { + } else if let [variant] = variants.as_slice() { // If there is a single variant, we don't need an operation on // the discriminant(s). Just use the most degenerate result. return self.call_substructure_method( @@ -1281,7 +1281,7 @@ impl<'a> MethodDef<'a> { trait_, type_ident, nonselflike_args, - &EnumMatching(0, &variants[0], Vec::new()), + &EnumMatching(0, variant, Vec::new()), ); } } diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 9c70f7ede8c..306490a4975 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -180,8 +180,8 @@ fn make_format_args( Ok((mut err, suggested)) => { if !suggested { if let ExprKind::Block(block, None) = &efmt.kind - && block.stmts.len() == 1 - && let StmtKind::Expr(expr) = &block.stmts[0].kind + && let [stmt] = block.stmts.as_slice() + && let StmtKind::Expr(expr) = &stmt.kind && let ExprKind::Path(None, path) = &expr.kind && path.is_potential_trivial_const_arg() { @@ -196,8 +196,8 @@ fn make_format_args( } else { let sugg_fmt = match args.explicit_args().len() { 0 => "{}".to_string(), - _ => { - format!("{}{{}}", "{} ".repeat(args.explicit_args().len())) + count => { + format!("{}{{}}", "{} ".repeat(count)) } }; err.span_suggestion( diff --git a/compiler/rustc_data_structures/src/transitive_relation.rs b/compiler/rustc_data_structures/src/transitive_relation.rs index 26b00e0af3a..e81ebb9a4be 100644 --- a/compiler/rustc_data_structures/src/transitive_relation.rs +++ b/compiler/rustc_data_structures/src/transitive_relation.rs @@ -203,9 +203,9 @@ impl TransitiveRelation { /// exists). See `postdom_upper_bound` for details. pub fn mutual_immediate_postdominator(&self, mut mubs: Vec) -> Option { loop { - match mubs.len() { - 0 => return None, - 1 => return Some(mubs[0]), + match mubs[..] { + [] => return None, + [mub] => return Some(mub), _ => { let m = mubs.pop().unwrap(); let n = mubs.pop().unwrap(); diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 627a0ebb4e5..3b88c63e21b 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -335,12 +335,11 @@ fn run_compiler( config.input = input; true // has input: normal compilation } - Ok(None) => match matches.free.len() { - 0 => false, // no input: we will exit early - 1 => panic!("make_input should have provided valid inputs"), - _ => default_early_dcx.early_fatal(format!( - "multiple input filenames provided (first two filenames are `{}` and `{}`)", - matches.free[0], matches.free[1], + Ok(None) => match matches.free.as_slice() { + [] => false, // no input: we will exit early + [_] => panic!("make_input should have provided valid inputs"), + [fst, snd, ..] => default_early_dcx.early_fatal(format!( + "multiple input filenames provided (first two filenames are `{fst}` and `{snd}`)" )), }, }; @@ -488,34 +487,30 @@ fn make_input( early_dcx: &EarlyDiagCtxt, free_matches: &[String], ) -> Result, ErrorGuaranteed> { - if free_matches.len() == 1 { - let ifile = &free_matches[0]; - if ifile == "-" { - let mut src = String::new(); - if io::stdin().read_to_string(&mut src).is_err() { - // Immediately stop compilation if there was an issue reading - // the input (for example if the input stream is not UTF-8). - let reported = early_dcx - .early_err("couldn't read from stdin, as it did not contain valid UTF-8"); - return Err(reported); - } - if let Ok(path) = env::var("UNSTABLE_RUSTDOC_TEST_PATH") { - let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE").expect( - "when UNSTABLE_RUSTDOC_TEST_PATH is set \ + let [ifile] = free_matches else { return Ok(None) }; + if ifile == "-" { + let mut src = String::new(); + if io::stdin().read_to_string(&mut src).is_err() { + // Immediately stop compilation if there was an issue reading + // the input (for example if the input stream is not UTF-8). + let reported = + early_dcx.early_err("couldn't read from stdin, as it did not contain valid UTF-8"); + return Err(reported); + } + if let Ok(path) = env::var("UNSTABLE_RUSTDOC_TEST_PATH") { + let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE").expect( + "when UNSTABLE_RUSTDOC_TEST_PATH is set \ UNSTABLE_RUSTDOC_TEST_LINE also needs to be set", - ); - let line = isize::from_str_radix(&line, 10) - .expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number"); - let file_name = FileName::doc_test_source_code(PathBuf::from(path), line); - Ok(Some(Input::Str { name: file_name, input: src })) - } else { - Ok(Some(Input::Str { name: FileName::anon_source_code(&src), input: src })) - } + ); + let line = isize::from_str_radix(&line, 10) + .expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number"); + let file_name = FileName::doc_test_source_code(PathBuf::from(path), line); + Ok(Some(Input::Str { name: file_name, input: src })) } else { - Ok(Some(Input::File(PathBuf::from(ifile)))) + Ok(Some(Input::Str { name: FileName::anon_source_code(&src), input: src })) } } else { - Ok(None) + Ok(Some(Input::File(PathBuf::from(ifile)))) } } diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 483b757f20c..04c7b252111 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -231,17 +231,17 @@ pub trait Emitter: Translate { ) { if let Some((sugg, rest)) = suggestions.split_first() { let msg = self.translate_message(&sugg.msg, fluent_args).map_err(Report::new).unwrap(); - if rest.is_empty() && + if rest.is_empty() // ^ if there is only one suggestion // don't display multi-suggestions as labels - sugg.substitutions.len() == 1 && + && let [substitution] = sugg.substitutions.as_slice() // don't display multipart suggestions as labels - sugg.substitutions[0].parts.len() == 1 && + && let [part] = substitution.parts.as_slice() // don't display long messages as labels - msg.split_whitespace().count() < 10 && + && msg.split_whitespace().count() < 10 // don't display multiline suggestions as labels - !sugg.substitutions[0].parts[0].snippet.contains('\n') && - ![ + && !part.snippet.contains('\n') + && ![ // when this style is set we want the suggestion to be a message, not inline SuggestionStyle::HideCodeAlways, // trivial suggestion for tooling's sake, never shown @@ -250,8 +250,8 @@ pub trait Emitter: Translate { SuggestionStyle::ShowAlways, ].contains(&sugg.style) { - let substitution = &sugg.substitutions[0].parts[0].snippet.trim(); - let msg = if substitution.is_empty() || sugg.style.hide_inline() { + let snippet = part.snippet.trim(); + let msg = if snippet.is_empty() || sugg.style.hide_inline() { // This substitution is only removal OR we explicitly don't want to show the // code inline (`hide_inline`). Therefore, we don't show the substitution. format!("help: {msg}") @@ -260,19 +260,18 @@ pub trait Emitter: Translate { format!( "help: {}{}: `{}`", msg, - if self.source_map().is_some_and(|sm| is_case_difference( - sm, - substitution, - sugg.substitutions[0].parts[0].span, - )) { + if self + .source_map() + .is_some_and(|sm| is_case_difference(sm, snippet, part.span,)) + { " (notice the capitalization)" } else { "" }, - substitution, + snippet, ) }; - primary_span.push_span_label(sugg.substitutions[0].parts[0].span, msg); + primary_span.push_span_label(part.span, msg); // We return only the modified primary_span suggestions.clear(); diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index ceebcd46a6f..aefbf05a1fc 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -2024,11 +2024,11 @@ pub fn a_or_an(s: &str) -> &'static str { /// /// Take a list ["a", "b", "c"] and output a display friendly version "a, b and c" pub fn display_list_with_comma_and(v: &[T]) -> String { - match v.len() { - 0 => "".to_string(), - 1 => v[0].to_string(), - 2 => format!("{} and {}", v[0], v[1]), - _ => format!("{}, {}", v[0], display_list_with_comma_and(&v[1..])), + match v { + [] => "".to_string(), + [a] => a.to_string(), + [a, b] => format!("{a} and {b}"), + [a, v @ ..] => format!("{a}, {}", display_list_with_comma_and(v)), } } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index c195d692588..7712915d490 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1306,12 +1306,12 @@ pub fn parse_macro_name_and_helper_attrs( // that it's of the form `#[proc_macro_derive(Foo)]` or // `#[proc_macro_derive(Foo, attributes(A, ..))]` let list = attr.meta_item_list()?; - if list.len() != 1 && list.len() != 2 { + let ([trait_attr] | [trait_attr, _]) = list.as_slice() else { dcx.emit_err(errors::AttrNoArguments { span: attr.span }); return None; - } - let Some(trait_attr) = list[0].meta_item() else { - dcx.emit_err(errors::NotAMetaItem { span: list[0].span() }); + }; + let Some(trait_attr) = trait_attr.meta_item() else { + dcx.emit_err(errors::NotAMetaItem { span: trait_attr.span() }); return None; }; let trait_ident = match trait_attr.ident() { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index e54f9486f6a..9893c8ff324 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2734,15 +2734,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else if let ty::RawPtr(ptr_ty, _) = expr_t.kind() && let ty::Adt(adt_def, _) = ptr_ty.kind() && let ExprKind::Field(base_expr, _) = expr.kind - && adt_def.variants().len() == 1 - && adt_def - .variants() - .iter() - .next() - .unwrap() - .fields - .iter() - .any(|f| f.ident(self.tcx) == field) + && let [variant] = &adt_def.variants().raw + && variant.fields.iter().any(|f| f.ident(self.tcx) == field) { err.multipart_suggestion( "to access the field, dereference first", diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index f14159dc35a..e0c0adac076 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -654,17 +654,17 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { traits::upcast_choices(self.tcx, source_trait_ref, target_trait_def_id); // must be exactly one trait ref or we'd get an ambig error etc - if upcast_trait_refs.len() != 1 { + let [upcast_trait_ref] = upcast_trait_refs.as_slice() else { span_bug!( self.span, "cannot uniquely upcast `{:?}` to `{:?}`: `{:?}`", source_trait_ref, target_trait_def_id, upcast_trait_refs - ); - } + ) + }; - upcast_trait_refs.into_iter().next().unwrap() + *upcast_trait_ref } fn instantiate_binder_with_fresh_vars(&self, value: ty::Binder<'tcx, T>) -> T diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 94133357a3e..61287d98676 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -321,19 +321,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); }; let suggest_for_privacy = - |err: &mut Diag<'_>, mut msg: String, sugg: Vec| { - if sugg.len() == 1 { - let msg = format!("\ + |err: &mut Diag<'_>, mut msg: String, suggs: Vec| { + if let [sugg] = suggs.as_slice() { + err.help(format!("\ trait `{}` provides `{item_name}` is implemented but not reachable", - sugg[0].trim() - ); - err.help(msg); + sugg.trim(), + )); } else { - msg += &format!(" but {} not reachable", pluralize!("is", sugg.len())); + msg += &format!(" but {} not reachable", pluralize!("is", suggs.len())); err.span_suggestions( span, msg, - sugg, + suggs, Applicability::MaybeIncorrect, ); } @@ -2988,11 +2987,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } if local_spans.primary_span().is_some() { - let msg = if local_preds.len() == 1 { + let msg = if let [local_pred] = local_preds.as_slice() { format!( "an implementation of `{}` might be missing for `{}`", - local_preds[0].trait_ref.print_trait_sugared(), - local_preds[0].self_ty() + local_pred.trait_ref.print_trait_sugared(), + local_pred.self_ty() ) } else { format!( @@ -3034,11 +3033,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } if foreign_spans.primary_span().is_some() { - let msg = if foreign_preds.len() == 1 { + let msg = if let [foreign_pred] = foreign_preds.as_slice() { format!( "the foreign item type `{}` doesn't implement `{}`", - foreign_preds[0].self_ty(), - foreign_preds[0].trait_ref.print_trait_sugared() + foreign_pred.self_ty(), + foreign_pred.trait_ref.print_trait_sugared() ) } else { format!( @@ -3388,26 +3387,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); self.suggest_use_candidates(candidates, |accessible_sugg, inaccessible_sugg, span| { - let suggest_for_access = |err: &mut Diag<'_>, mut msg: String, sugg: Vec<_>| { + let suggest_for_access = |err: &mut Diag<'_>, mut msg: String, suggs: Vec<_>| { msg += &format!( "; perhaps you want to import {one_of}", - one_of = if sugg.len() == 1 { "it" } else { "one of them" }, + one_of = if suggs.len() == 1 { "it" } else { "one of them" }, ); - err.span_suggestions(span, msg, sugg, Applicability::MaybeIncorrect); + err.span_suggestions(span, msg, suggs, Applicability::MaybeIncorrect); }; - let suggest_for_privacy = |err: &mut Diag<'_>, sugg: Vec| { + let suggest_for_privacy = |err: &mut Diag<'_>, suggs: Vec| { let msg = format!( "{this_trait_is} implemented but not reachable", - this_trait_is = if sugg.len() == 1 { - format!("trait `{}` which provides `{item_name}` is", sugg[0].trim()) + this_trait_is = if let [sugg] = suggs.as_slice() { + format!("trait `{}` which provides `{item_name}` is", sugg.trim()) } else { format!("the following traits which provide `{item_name}` are") } ); - if sugg.len() == 1 { + if suggs.len() == 1 { err.help(msg); } else { - err.span_suggestions(span, msg, sugg, Applicability::MaybeIncorrect); + err.span_suggestions(span, msg, suggs, Applicability::MaybeIncorrect); } }; if accessible_sugg.is_empty() { diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index ce7d203d8c0..d7fd41c0ad7 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -527,11 +527,11 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { // Lint for constants that look like binding identifiers (#7526) if let PatKind::Path(hir::QPath::Resolved(None, path)) = p.kind { if let Res::Def(DefKind::Const, _) = path.res { - if path.segments.len() == 1 { + if let [segment] = path.segments { NonUpperCaseGlobals::check_upper_case( cx, "constant in pattern", - &path.segments[0].ident, + &segment.ident, ); } } diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index f3196cfed53..60309f12075 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -211,15 +211,12 @@ fn lint_overflowing_range_endpoint<'tcx>( if !is_range_literal(struct_expr) { return false; }; - let ExprKind::Struct(_, eps, _) = &struct_expr.kind else { return false }; - if eps.len() != 2 { - return false; - } + let ExprKind::Struct(_, [start, end], _) = &struct_expr.kind else { return false }; // We can suggest using an inclusive range // (`..=`) instead only if it is the `end` that is // overflowing and only by 1. - if !(eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max) { + if !(end.expr.hir_id == expr.hir_id && lit_val - 1 == max) { return false; }; @@ -232,7 +229,7 @@ fn lint_overflowing_range_endpoint<'tcx>( }; let sub_sugg = if expr.span.lo() == lit_span.lo() { - let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) else { return false }; + let Ok(start) = cx.sess().source_map().span_to_snippet(start.span) else { return false }; UseInclusiveRange::WithoutParen { sugg: struct_expr.span.shrink_to_lo().to(lit_span.shrink_to_hi()), start, diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 795333224ba..cbf6cb08330 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -801,7 +801,7 @@ trait UnusedDelimLint { return; } let spans = match value.kind { - ast::ExprKind::Block(ref block, None) if block.stmts.len() == 1 => block.stmts[0] + ast::ExprKind::Block(ref block, None) if let [stmt] = block.stmts.as_slice() => stmt .span .find_ancestor_inside(value.span) .map(|span| (value.span.with_hi(span.lo()), value.span.with_lo(span.hi()))), @@ -1537,14 +1537,12 @@ impl UnusedImportBraces { } // Trigger the lint only if there is one nested item - if items.len() != 1 { - return; - } + let [(tree, _)] = items.as_slice() else { return }; // Trigger the lint if the nested item is a non-self single item - let node_name = match items[0].0.kind { + let node_name = match tree.kind { ast::UseTreeKind::Simple(rename) => { - let orig_ident = items[0].0.prefix.segments.last().unwrap().ident; + let orig_ident = tree.prefix.segments.last().unwrap().ident; if orig_ident.name == kw::SelfLower { return; } 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 64c6ff952c6..5e6e1a9c0a4 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -483,9 +483,11 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { // Check if the match is exhaustive. let witnesses = report.non_exhaustiveness_witnesses; if !witnesses.is_empty() { - if source == hir::MatchSource::ForLoopDesugar && arms.len() == 2 { + if source == hir::MatchSource::ForLoopDesugar + && let [_, snd_arm] = *arms + { // the for loop pattern is not irrefutable - let pat = &self.thir[arms[1]].pattern; + let pat = &self.thir[snd_arm].pattern; // `pat` should be `Some()` from a desugared for loop. debug_assert_eq!(pat.span.desugaring_kind(), Some(DesugaringKind::ForLoop)); let PatKind::Variant { ref subpatterns, .. } = pat.kind else { bug!() }; diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index c3f4bbf1a65..31b20775194 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -350,8 +350,8 @@ fn bcb_filtered_successors<'a, 'tcx>(terminator: &'a Terminator<'tcx>) -> Covera // An inline asm terminator can normally be chained, except when it diverges or uses asm // goto. InlineAsm { ref targets, .. } => { - if targets.len() == 1 { - CoverageSuccessors::Chainable(targets[0]) + if let [target] = targets[..] { + CoverageSuccessors::Chainable(target) } else { CoverageSuccessors::NotChainable(targets) } diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs index e4fec786814..49e41c35f1f 100644 --- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs +++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs @@ -309,11 +309,11 @@ fn verify_candidate_branch<'tcx>( ) -> bool { // In order for the optimization to be correct, the branch must... // ...have exactly one statement - if branch.statements.len() != 1 { + let [statement] = branch.statements.as_slice() else { return false; - } + }; // ...assign the discriminant of `place` in that statement - let StatementKind::Assign(boxed) = &branch.statements[0].kind else { return false }; + let StatementKind::Assign(boxed) = &statement.kind else { return false }; let (discr_place, Rvalue::Discriminant(from_place)) = &**boxed else { return false }; if *from_place != place { return false; diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 2fc5f7e536b..1589653968c 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -264,9 +264,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { }; // It's definitely not a clone if there are multiple arguments - if args.len() != 1 { - return; - } + let [arg] = &args[..] else { return }; let Some(destination_block) = *target else { return }; @@ -280,7 +278,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { // These types are easily available from locals, so check that before // doing DefId lookups to figure out what we're actually calling. - let arg_ty = args[0].node.ty(self.local_decls, self.tcx); + let arg_ty = arg.node.ty(self.local_decls, self.tcx); let ty::Ref(_region, inner_ty, Mutability::Not) = *arg_ty.kind() else { return }; diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 746d423b7a9..491ae1c0d08 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -898,8 +898,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.param_env, adt_def.non_enum_variant().fields[field].ty(self.tcx, args), ); - if fields.len() == 1 { - let src_ty = fields.raw[0].ty(self.body, self.tcx); + if let [field] = fields.raw.as_slice() { + let src_ty = field.ty(self.body, self.tcx); if !self.mir_assign_valid_types(src_ty, dest_ty) { self.fail(location, "union field has the wrong type"); } @@ -967,11 +967,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.fail(location, "RawPtr should be in runtime MIR only"); } - if fields.len() != 2 { - self.fail(location, "raw pointer aggregate must have 2 fields"); - } else { - let data_ptr_ty = fields.raw[0].ty(self.body, self.tcx); - let metadata_ty = fields.raw[1].ty(self.body, self.tcx); + if let [data_ptr, metadata] = fields.raw.as_slice() { + let data_ptr_ty = data_ptr.ty(self.body, self.tcx); + let metadata_ty = metadata.ty(self.body, self.tcx); if let ty::RawPtr(in_pointee, in_mut) = data_ptr_ty.kind() { if *in_mut != mutability { self.fail(location, "input and output mutability must match"); @@ -998,6 +996,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.fail(location, "metadata for pointer-to-thin must be unit"); } } + } else { + self.fail(location, "raw pointer aggregate must have 2 fields"); } } }, diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index ccf8dcdf0b6..cf5d65708ab 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -694,12 +694,12 @@ impl<'a> Parser<'a> { // `foo: ` ExprKind::Path(None, ast::Path { segments, .. }), token::Ident(kw::For | kw::Loop | kw::While, IdentIsRaw::No), - ) if segments.len() == 1 => { + ) if let [segment] = segments.as_slice() => { let snapshot = self.create_snapshot_for_diagnostic(); let label = Label { ident: Ident::from_str_and_span( - &format!("'{}", segments[0].ident), - segments[0].ident.span, + &format!("'{}", segment.ident), + segment.ident.span, ), }; match self.parse_expr_labeled(label, false) { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index baa5eb2df63..8775d792c3d 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -471,9 +471,8 @@ impl<'a> Parser<'a> { Err(mut err) => { // Maybe the user misspelled `macro_rules` (issue #91227) if self.token.is_ident() - && path.segments.len() == 1 - && edit_distance("macro_rules", &path.segments[0].ident.to_string(), 2) - .is_some() + && let [segment] = path.segments.as_slice() + && edit_distance("macro_rules", &segment.ident.to_string(), 2).is_some() { err.span_suggestion( path.span, diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 70d2c98d4f1..6f82d6b9826 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -826,7 +826,8 @@ impl<'a> Parser<'a> { // We can only resolve single-segment paths at the moment, because multi-segment paths // require type-checking: see `visit_generic_arg` in `src/librustc_resolve/late.rs`. ast::ExprKind::Path(None, path) - if path.segments.len() == 1 && path.segments[0].args.is_none() => + if let [segment] = path.segments.as_slice() + && segment.args.is_none() => { true } diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index b3efb87a4a2..8c8b2241c0c 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -672,7 +672,7 @@ impl<'a> Parser<'a> { match &expr.kind { ExprKind::Path(None, ast::Path { segments, .. }) - if segments.len() == 1 => + if let [segment] = segments.as_slice() => { if self.token == token::Colon && self.look_ahead(1, |token| { @@ -689,8 +689,8 @@ impl<'a> Parser<'a> { let snapshot = self.create_snapshot_for_diagnostic(); let label = Label { ident: Ident::from_str_and_span( - &format!("'{}", segments[0].ident), - segments[0].ident.span, + &format!("'{}", segment.ident), + segment.ident.span, ), }; match self.parse_expr_labeled(label, false) { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index a0d0d80b957..a6195733fe5 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2207,8 +2207,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { attr.name_or_empty(), sym::allow | sym::warn | sym::deny | sym::forbid | sym::expect ) && let Some(meta) = attr.meta_item_list() - && meta.len() == 1 - && let Some(item) = meta[0].meta_item() + && let [meta] = meta.as_slice() + && let Some(item) = meta.meta_item() && let MetaItemKind::NameValue(_) = &item.kind && item.path == sym::reason { diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs index 0537d3a69f6..5d871bacb1d 100644 --- a/compiler/rustc_passes/src/debugger_visualizer.rs +++ b/compiler/rustc_passes/src/debugger_visualizer.rs @@ -19,9 +19,7 @@ impl DebuggerVisualizerCollector<'_> { return; }; - let hint = if hints.len() == 1 { - &hints[0] - } else { + let [hint] = hints.as_slice() else { self.sess.dcx().emit_err(DebugVisualizerInvalid { span: attr.span }); return; }; diff --git a/compiler/rustc_query_system/src/dep_graph/debug.rs b/compiler/rustc_query_system/src/dep_graph/debug.rs index 4d009d63de5..12ed5742711 100644 --- a/compiler/rustc_query_system/src/dep_graph/debug.rs +++ b/compiler/rustc_query_system/src/dep_graph/debug.rs @@ -46,15 +46,14 @@ pub struct EdgeFilter { impl EdgeFilter { pub fn new(test: &str) -> Result> { - let parts: Vec<_> = test.split("->").collect(); - if parts.len() != 2 { - Err(format!("expected a filter like `a&b -> c&d`, not `{test}`").into()) - } else { + if let [source, target] = *test.split("->").collect::>() { Ok(EdgeFilter { - source: DepNodeFilter::new(parts[0]), - target: DepNodeFilter::new(parts[1]), + source: DepNodeFilter::new(source), + target: DepNodeFilter::new(target), index_to_node: Lock::new(FxHashMap::default()), }) + } else { + Err(format!("expected a filter like `a&b -> c&d`, not `{test}`").into()) } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f844930ad26..6fcb4cfd8ad 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -445,8 +445,8 @@ impl<'a> PathSource<'a> { Some(ExprKind::Call(call_expr, _)) => match &call_expr.kind { // the case of `::some_crate()` ExprKind::Path(_, path) - if path.segments.len() == 2 - && path.segments[0].ident.name == kw::PathRoot => + if let [segment, _] = path.segments.as_slice() + && segment.ident.name == kw::PathRoot => { "external crate" } @@ -2395,15 +2395,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } fn future_proof_import(&mut self, use_tree: &UseTree) { - let segments = &use_tree.prefix.segments; - if !segments.is_empty() { - let ident = segments[0].ident; + if let [segment, rest @ ..] = use_tree.prefix.segments.as_slice() { + let ident = segment.ident; if ident.is_path_segment_keyword() || ident.span.is_rust_2015() { return; } let nss = match use_tree.kind { - UseTreeKind::Simple(..) if segments.len() == 1 => &[TypeNS, ValueNS][..], + UseTreeKind::Simple(..) if rest.is_empty() => &[TypeNS, ValueNS][..], _ => &[TypeNS], }; let report_error = |this: &Self, ns| { @@ -3999,16 +3998,15 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { if this.should_report_errs() { if candidates.is_empty() { - if path.len() == 2 && prefix_path.len() == 1 { + if path.len() == 2 + && let [segment] = prefix_path + { // Delay to check whether methond name is an associated function or not // ``` // let foo = Foo {}; // foo::bar(); // possibly suggest to foo.bar(); //``` - err.stash( - prefix_path[0].ident.span, - rustc_errors::StashKey::CallAssocMethod, - ); + err.stash(segment.ident.span, rustc_errors::StashKey::CallAssocMethod); } else { // When there is no suggested imports, we can just emit the error // and suggestions immediately. Note that we bypass the usually error diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index f126563fe58..9031c96027e 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -650,14 +650,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { let typo_sugg = self .lookup_typo_candidate(path, following_seg, source.namespace(), is_expected) .to_opt_suggestion(); - if path.len() == 1 + if let [segment] = path && !matches!(source, PathSource::Delegation) && self.self_type_is_available() { if let Some(candidate) = self.lookup_assoc_candidate(ident, ns, is_expected, source.is_call()) { - let self_is_available = self.self_value_is_available(path[0].ident.span); + let self_is_available = self.self_value_is_available(segment.ident.span); // Account for `Foo { field }` when suggesting `self.field` so we result on // `Foo { field: self.field }`. let pre = match source { @@ -665,7 +665,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { if expr .fields .iter() - .any(|f| f.ident == path[0].ident && f.is_shorthand) => + .any(|f| f.ident == segment.ident && f.is_shorthand) => { format!("{path_str}: ") } @@ -1258,8 +1258,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { ) }) .collect(); - if targets.len() == 1 { - let target = targets[0]; + if let [target] = targets.as_slice() { return Some(TypoSuggestion::single_item_from_ident(target.0.ident, target.1)); } } @@ -2104,8 +2103,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { filter_fn: &impl Fn(Res) -> bool, ) -> TypoCandidate { let mut names = Vec::new(); - if path.len() == 1 { - let mut ctxt = path.last().unwrap().ident.span.ctxt(); + if let [segment] = path { + let mut ctxt = segment.ident.span.ctxt(); // Search in lexical scope. // Walk backwards up the ribs in scope and collect candidates. diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 64ae0d82952..77808df973c 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -108,8 +108,8 @@ pub(crate) fn sub_namespace_match( // `format!("{}", path)`, because that tries to insert // line-breaks and is slow. fn fast_print_path(path: &ast::Path) -> Symbol { - if path.segments.len() == 1 { - path.segments[0].ident.name + if let [segment] = path.segments.as_slice() { + segment.ident.name } else { let mut path_str = String::with_capacity(64); for (i, segment) in path.segments.iter().enumerate() { @@ -724,10 +724,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Possibly apply the macro helper hack if deleg_impl.is_none() && kind == Some(MacroKind::Bang) - && path.len() == 1 - && path[0].ident.span.ctxt().outer_expn_data().local_inner_macros + && let [segment] = path.as_slice() + && segment.ident.span.ctxt().outer_expn_data().local_inner_macros { - let root = Ident::new(kw::DollarCrate, path[0].ident.span); + let root = Ident::new(kw::DollarCrate, segment.ident.span); path.insert(0, Segment::from_ident(root)); } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index bf54aae1cfe..3cbe502c91e 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -912,16 +912,9 @@ mod parse { match v { None => false, Some(s) => { - let parts = s.split('=').collect::>(); - if parts.len() != 2 { - return false; - } - let crate_name = parts[0].to_string(); - let fuel = parts[1].parse::(); - if fuel.is_err() { - return false; - } - *slot = Some((crate_name, fuel.unwrap())); + let [crate_name, fuel] = *s.split('=').collect::>() else { return false }; + let Ok(fuel) = fuel.parse::() else { return false }; + *slot = Some((crate_name.to_string(), fuel)); true } } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 946947124c6..8ce51ba2463 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -3149,11 +3149,10 @@ impl Target { if let Some(a) = o.as_array() { for o in a { if let Some(s) = o.as_str() { - let p = s.split('=').collect::>(); - if p.len() == 2 { - let k = p[0].to_string(); - let v = p[1].to_string(); - base.$key_name.to_mut().push((k.into(), v.into())); + if let [k, v] = *s.split('=').collect::>() { + base.$key_name + .to_mut() + .push((k.to_string().into(), v.to_string().into())) } } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 2ce1b955af5..4a79ff38255 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -943,8 +943,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // The current method call returns `Result<_, ()>` && self.can_eq(obligation.param_env, ty, found_ty) // There's a single argument in the method call and it is a closure - && args.len() == 1 - && let Some(arg) = args.get(0) + && let [arg] = args && let hir::ExprKind::Closure(closure) = arg.kind // The closure has a block for its body with no tail expression && let body = self.tcx.hir().body(closure.body) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index 3a082893c5c..f656f9b0e38 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -73,10 +73,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } }); - let impl_def_id_and_args = if self_match_impls.len() == 1 { - self_match_impls[0] - } else if fuzzy_match_impls.len() == 1 { - fuzzy_match_impls[0] + let impl_def_id_and_args = if let [impl_] = self_match_impls[..] { + impl_ + } else if let [impl_] = fuzzy_match_impls[..] { + impl_ } else { return None; }; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 0d15ef55e24..9269177eb50 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -5300,7 +5300,8 @@ impl<'v> Visitor<'v> for FindTypeParam { match ty.kind { hir::TyKind::Ptr(_) | hir::TyKind::Ref(..) | hir::TyKind::TraitObject(..) => {} hir::TyKind::Path(hir::QPath::Resolved(None, path)) - if path.segments.len() == 1 && path.segments[0].ident.name == self.param => + if let [segment] = path.segments + && segment.ident.name == self.param => { if !self.nested { debug!(?ty, "FindTypeParam::visit_ty"); -- cgit 1.4.1-3-g733a5 From ae696f847dee523df6afed14468de70fc6479552 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Thu, 8 Aug 2024 01:46:16 +0000 Subject: Split `ColorConfig` off of `HumanReadableErrorType` The previous setup tied two unrelated things together. Splitting these two is a better model. --- compiler/rustc_errors/src/emitter.rs | 17 +++------------ compiler/rustc_errors/src/json.rs | 9 +++++--- compiler/rustc_errors/src/json/tests.rs | 3 ++- compiler/rustc_interface/src/tests.rs | 3 ++- compiler/rustc_session/src/config.rs | 38 ++++++++++++++++++++------------- compiler/rustc_session/src/session.rs | 30 +++++++++++++++----------- src/librustdoc/config.rs | 5 +++-- src/librustdoc/core.rs | 7 +++--- src/librustdoc/doctest.rs | 4 ++-- 9 files changed, 62 insertions(+), 54 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 88ed3128164..5bd3b328cb8 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -43,20 +43,9 @@ const DEFAULT_COLUMN_WIDTH: usize = 140; /// Describes the way the content of the `rendered` field of the json output is generated #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum HumanReadableErrorType { - Default(ColorConfig), - AnnotateSnippet(ColorConfig), - Short(ColorConfig), -} - -impl HumanReadableErrorType { - /// Returns a (`short`, `color`) tuple - pub fn unzip(self) -> (bool, ColorConfig) { - match self { - HumanReadableErrorType::Default(cc) => (false, cc), - HumanReadableErrorType::Short(cc) => (true, cc), - HumanReadableErrorType::AnnotateSnippet(cc) => (false, cc), - } - } + Default, + AnnotateSnippet, + Short, } #[derive(Clone, Copy, Debug)] diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 42a28bc7890..02a0de201ed 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -55,6 +55,7 @@ pub struct JsonEmitter { ignored_directories_in_source_blocks: Vec, #[setters(skip)] json_rendered: HumanReadableErrorType, + color_config: ColorConfig, diagnostic_width: Option, macro_backtrace: bool, track_diagnostics: bool, @@ -68,6 +69,7 @@ impl JsonEmitter { fallback_bundle: LazyFallbackBundle, pretty: bool, json_rendered: HumanReadableErrorType, + color_config: ColorConfig, ) -> JsonEmitter { JsonEmitter { dst: IntoDynSyncSend(dst), @@ -79,6 +81,7 @@ impl JsonEmitter { ui_testing: false, ignored_directories_in_source_blocks: Vec::new(), json_rendered, + color_config, diagnostic_width: None, macro_backtrace: false, track_diagnostics: false, @@ -173,7 +176,7 @@ impl Emitter for JsonEmitter { } fn should_show_explain(&self) -> bool { - !matches!(self.json_rendered, HumanReadableErrorType::Short(_)) + !matches!(self.json_rendered, HumanReadableErrorType::Short) } } @@ -353,8 +356,8 @@ impl Diagnostic { let buf = BufWriter::default(); let mut dst: Destination = Box::new(buf.clone()); - let (short, color_config) = je.json_rendered.unzip(); - match color_config { + let short = matches!(je.json_rendered, HumanReadableErrorType::Short); + match je.color_config { ColorConfig::Always | ColorConfig::Auto => dst = Box::new(termcolor::Ansi::new(dst)), ColorConfig::Never => {} } diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index e3549fc3aa5..6af376d7afd 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -50,7 +50,8 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { sm, fallback_bundle, true, // pretty - HumanReadableErrorType::Short(ColorConfig::Never), + HumanReadableErrorType::Short, + ColorConfig::Never, ); let span = Span::with_root_ctxt(BytePos(span.0), BytePos(span.1)); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index ce3b2f77f21..34f2dca7c42 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -315,7 +315,8 @@ fn test_search_paths_tracking_hash_different_order() { let early_dcx = EarlyDiagCtxt::new(JSON); const JSON: ErrorOutputType = ErrorOutputType::Json { pretty: false, - json_rendered: HumanReadableErrorType::Default(ColorConfig::Never), + json_rendered: HumanReadableErrorType::Default, + color_config: ColorConfig::Never, }; let push = |opts: &mut Options, search_path| { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 20c14a98502..95d171409d8 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -602,7 +602,7 @@ impl OutputType { #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum ErrorOutputType { /// Output meant for the consumption of humans. - HumanReadable(HumanReadableErrorType), + HumanReadable(HumanReadableErrorType, ColorConfig), /// Output that's consumed by other tools such as `rustfix` or the `RLS`. Json { /// Render the JSON in a human readable way (with indents and newlines). @@ -610,12 +610,13 @@ pub enum ErrorOutputType { /// The JSON output includes a `rendered` field that includes the rendered /// human output. json_rendered: HumanReadableErrorType, + color_config: ColorConfig, }, } impl Default for ErrorOutputType { fn default() -> Self { - Self::HumanReadable(HumanReadableErrorType::Default(ColorConfig::Auto)) + Self::HumanReadable(HumanReadableErrorType::Default, ColorConfig::Auto) } } @@ -1631,6 +1632,7 @@ pub fn parse_color(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Col /// Possible json config files pub struct JsonConfig { pub json_rendered: HumanReadableErrorType, + pub json_color: ColorConfig, json_artifact_notifications: bool, pub json_unused_externs: JsonUnusedExterns, json_future_incompat: bool, @@ -1668,8 +1670,7 @@ impl JsonUnusedExterns { /// The first value returned is how to render JSON diagnostics, and the second /// is whether or not artifact notifications are enabled. pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> JsonConfig { - let mut json_rendered: fn(ColorConfig) -> HumanReadableErrorType = - HumanReadableErrorType::Default; + let mut json_rendered = HumanReadableErrorType::Default; let mut json_color = ColorConfig::Never; let mut json_artifact_notifications = false; let mut json_unused_externs = JsonUnusedExterns::No; @@ -1696,7 +1697,8 @@ pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Json } JsonConfig { - json_rendered: json_rendered(json_color), + json_rendered, + json_color, json_artifact_notifications, json_unused_externs, json_future_incompat, @@ -1708,6 +1710,7 @@ pub fn parse_error_format( early_dcx: &mut EarlyDiagCtxt, matches: &getopts::Matches, color: ColorConfig, + json_color: ColorConfig, json_rendered: HumanReadableErrorType, ) -> ErrorOutputType { // We need the `opts_present` check because the driver will send us Matches @@ -1717,18 +1720,22 @@ pub fn parse_error_format( let error_format = if matches.opts_present(&["error-format".to_owned()]) { match matches.opt_str("error-format").as_deref() { None | Some("human") => { - ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)) + ErrorOutputType::HumanReadable(HumanReadableErrorType::Default, color) } Some("human-annotate-rs") => { - ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet(color)) + ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet, color) } - Some("json") => ErrorOutputType::Json { pretty: false, json_rendered }, - Some("pretty-json") => ErrorOutputType::Json { pretty: true, json_rendered }, - Some("short") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Short(color)), - + Some("json") => { + ErrorOutputType::Json { pretty: false, json_rendered, color_config: json_color } + } + Some("pretty-json") => { + ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color } + } + Some("short") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Short, color), Some(arg) => { early_dcx.abort_if_error_and_set_error_format(ErrorOutputType::HumanReadable( - HumanReadableErrorType::Default(color), + HumanReadableErrorType::Default, + color, )); early_dcx.early_fatal(format!( "argument for `--error-format` must be `human`, `json` or \ @@ -1737,7 +1744,7 @@ pub fn parse_error_format( } } } else { - ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)) + ErrorOutputType::HumanReadable(HumanReadableErrorType::Default, color) }; match error_format { @@ -1791,7 +1798,7 @@ fn check_error_format_stability( if let ErrorOutputType::Json { pretty: true, .. } = error_format { early_dcx.early_fatal("`--error-format=pretty-json` is unstable"); } - if let ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet(_)) = + if let ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet, _) = error_format { early_dcx.early_fatal("`--error-format=human-annotate-rs` is unstable"); @@ -2392,12 +2399,13 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let JsonConfig { json_rendered, + json_color, json_artifact_notifications, json_unused_externs, json_future_incompat, } = parse_json(early_dcx, matches); - let error_format = parse_error_format(early_dcx, matches, color, json_rendered); + let error_format = parse_error_format(early_dcx, matches, color, json_color, json_rendered); early_dcx.abort_if_error_and_set_error_format(error_format); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index be67baf57f6..c0fa377f8ba 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -950,10 +950,10 @@ fn default_emitter( t => t, }; match sopts.error_format { - config::ErrorOutputType::HumanReadable(kind) => { - let (short, color_config) = kind.unzip(); + config::ErrorOutputType::HumanReadable(kind, color_config) => { + let short = matches!(kind, HumanReadableErrorType::Short); - if let HumanReadableErrorType::AnnotateSnippet(_) = kind { + if let HumanReadableErrorType::AnnotateSnippet = kind { let emitter = AnnotateSnippetEmitter::new( Some(source_map), bundle, @@ -978,13 +978,14 @@ fn default_emitter( Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing)) } } - config::ErrorOutputType::Json { pretty, json_rendered } => Box::new( + config::ErrorOutputType::Json { pretty, json_rendered, color_config } => Box::new( JsonEmitter::new( Box::new(io::BufWriter::new(io::stderr())), source_map, fallback_bundle, pretty, json_rendered, + color_config, ) .registry(Some(registry)) .fluent_bundle(bundle) @@ -1425,20 +1426,23 @@ fn mk_emitter(output: ErrorOutputType) -> Box { let fallback_bundle = fallback_fluent_bundle(vec![rustc_errors::DEFAULT_LOCALE_RESOURCE], false); let emitter: Box = match output { - config::ErrorOutputType::HumanReadable(kind) => { - let (short, color_config) = kind.unzip(); + config::ErrorOutputType::HumanReadable(kind, color_config) => { + let short = matches!(kind, HumanReadableErrorType::Short); Box::new( HumanEmitter::new(stderr_destination(color_config), fallback_bundle) .short_message(short), ) } - config::ErrorOutputType::Json { pretty, json_rendered } => Box::new(JsonEmitter::new( - Box::new(io::BufWriter::new(io::stderr())), - Lrc::new(SourceMap::new(FilePathMapping::empty())), - fallback_bundle, - pretty, - json_rendered, - )), + config::ErrorOutputType::Json { pretty, json_rendered, color_config } => { + Box::new(JsonEmitter::new( + Box::new(io::BufWriter::new(io::stderr())), + Lrc::new(SourceMap::new(FilePathMapping::empty())), + fallback_bundle, + pretty, + json_rendered, + color_config, + )) + } }; emitter } diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index e4549796b3e..9c7a9f8467f 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -362,9 +362,10 @@ impl Options { } let color = config::parse_color(early_dcx, matches); - let config::JsonConfig { json_rendered, json_unused_externs, .. } = + let config::JsonConfig { json_rendered, json_unused_externs, json_color, .. } = config::parse_json(early_dcx, matches); - let error_format = config::parse_error_format(early_dcx, matches, color, json_rendered); + let error_format = + config::parse_error_format(early_dcx, matches, color, json_color, json_rendered); let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_default(); let codegen_options = CodegenOptions::build(early_dcx, matches); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index fea31e7ecbc..ae3456e1399 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -138,8 +138,8 @@ pub(crate) fn new_dcx( false, ); let emitter: Box = match error_format { - ErrorOutputType::HumanReadable(kind) => { - let (short, color_config) = kind.unzip(); + ErrorOutputType::HumanReadable(kind, color_config) => { + let short = matches!(kind, HumanReadableErrorType::Short); Box::new( HumanEmitter::new(stderr_destination(color_config), fallback_bundle) .sm(source_map.map(|sm| sm as _)) @@ -150,7 +150,7 @@ pub(crate) fn new_dcx( .ui_testing(unstable_opts.ui_testing), ) } - ErrorOutputType::Json { pretty, json_rendered } => { + ErrorOutputType::Json { pretty, json_rendered, color_config } => { let source_map = source_map.unwrap_or_else(|| { Lrc::new(source_map::SourceMap::new(source_map::FilePathMapping::empty())) }); @@ -161,6 +161,7 @@ pub(crate) fn new_dcx( fallback_bundle, pretty, json_rendered, + color_config, ) .ui_testing(unstable_opts.ui_testing) .diagnostic_width(diagnostic_width) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 41eb142dd1e..68044396048 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -422,8 +422,8 @@ fn run_test( path_for_rustdoc.to_str().expect("target path must be valid unicode") } }); - if let ErrorOutputType::HumanReadable(kind) = rustdoc_options.error_format { - let (short, color_config) = kind.unzip(); + if let ErrorOutputType::HumanReadable(kind, color_config) = rustdoc_options.error_format { + let short = matches!(kind, HumanReadableErrorType::Short); if short { compiler.arg("--error-format").arg("short"); -- cgit 1.4.1-3-g733a5 From 95c1c34fff6675910986c93c3fea3c03e9810f6a Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Thu, 8 Aug 2024 14:43:27 +0000 Subject: review comments --- compiler/rustc_errors/src/emitter.rs | 6 ++++++ compiler/rustc_errors/src/json.rs | 4 ++-- compiler/rustc_session/src/session.rs | 4 ++-- src/librustdoc/core.rs | 2 +- src/librustdoc/doctest.rs | 2 +- 5 files changed, 12 insertions(+), 6 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 5bd3b328cb8..9f4d9263f0f 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -48,6 +48,12 @@ pub enum HumanReadableErrorType { Short, } +impl HumanReadableErrorType { + pub fn short(&self) -> bool { + *self == HumanReadableErrorType::Short + } +} + #[derive(Clone, Copy, Debug)] struct Margin { /// The available whitespace in the left that can be consumed when centering. diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 02a0de201ed..32e59f9ab03 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -176,7 +176,7 @@ impl Emitter for JsonEmitter { } fn should_show_explain(&self) -> bool { - !matches!(self.json_rendered, HumanReadableErrorType::Short) + !self.json_rendered.short() } } @@ -356,7 +356,7 @@ impl Diagnostic { let buf = BufWriter::default(); let mut dst: Destination = Box::new(buf.clone()); - let short = matches!(je.json_rendered, HumanReadableErrorType::Short); + let short = je.json_rendered.short(); match je.color_config { ColorConfig::Always | ColorConfig::Auto => dst = Box::new(termcolor::Ansi::new(dst)), ColorConfig::Never => {} diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index c0fa377f8ba..672dddf871e 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -951,7 +951,7 @@ fn default_emitter( }; match sopts.error_format { config::ErrorOutputType::HumanReadable(kind, color_config) => { - let short = matches!(kind, HumanReadableErrorType::Short); + let short = kind.short(); if let HumanReadableErrorType::AnnotateSnippet = kind { let emitter = AnnotateSnippetEmitter::new( @@ -1427,7 +1427,7 @@ fn mk_emitter(output: ErrorOutputType) -> Box { fallback_fluent_bundle(vec![rustc_errors::DEFAULT_LOCALE_RESOURCE], false); let emitter: Box = match output { config::ErrorOutputType::HumanReadable(kind, color_config) => { - let short = matches!(kind, HumanReadableErrorType::Short); + let short = kind.short(); Box::new( HumanEmitter::new(stderr_destination(color_config), fallback_bundle) .short_message(short), diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index ae3456e1399..08a4a3f3fb2 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -139,7 +139,7 @@ pub(crate) fn new_dcx( ); let emitter: Box = match error_format { ErrorOutputType::HumanReadable(kind, color_config) => { - let short = matches!(kind, HumanReadableErrorType::Short); + let short = kind.short(); Box::new( HumanEmitter::new(stderr_destination(color_config), fallback_bundle) .sm(source_map.map(|sm| sm as _)) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 68044396048..08d6a5a52b2 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -423,7 +423,7 @@ fn run_test( } }); if let ErrorOutputType::HumanReadable(kind, color_config) = rustdoc_options.error_format { - let short = matches!(kind, HumanReadableErrorType::Short); + let short = kind.short(); if short { compiler.arg("--error-format").arg("short"); -- cgit 1.4.1-3-g733a5 From 38874a692738f23b17d20a81bb906701303c0474 Mon Sep 17 00:00:00 2001 From: Folkert Date: Thu, 8 Aug 2024 23:55:59 +0200 Subject: use stable sort to sort multipart diagnostics --- compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs | 2 +- compiler/rustc_errors/src/diagnostic.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 7a925705806..a58c7c43246 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1124,8 +1124,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { err.multipart_suggestion( "consider moving the expression out of the loop so it is only moved once", vec![ - (parent.span, "value".to_string()), (span.shrink_to_lo(), format!("let mut value = {value};{indent}")), + (parent.span, "value".to_string()), ], Applicability::MaybeIncorrect, ); diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 67ca6d50cca..fae8b5647fc 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -920,8 +920,8 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { applicability: Applicability, style: SuggestionStyle, ) -> &mut Self { - suggestion.sort_unstable(); - suggestion.dedup_by(|(s1, m1), (s2, m2)| s1.source_equal(*s2) && m1 == m2); + let mut seen = crate::FxHashSet::default(); + suggestion.retain(|(span, msg)| seen.insert((span.lo(), span.hi(), msg.clone()))); let parts = suggestion .into_iter() -- cgit 1.4.1-3-g733a5 From c256de2253315d4668c417291b9ea5115b49667c Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 20 Mar 2024 19:49:20 +0100 Subject: Update std and compiler --- compiler/rustc_errors/src/diagnostic_impls.rs | 1 + compiler/rustc_middle/src/lib.rs | 2 +- compiler/rustc_target/src/lib.rs | 2 +- compiler/rustc_transmute/src/layout/nfa.rs | 1 + compiler/rustc_type_ir/src/fold.rs | 2 ++ library/core/src/lib.rs | 2 +- library/std/src/lib.rs | 2 +- 7 files changed, 8 insertions(+), 4 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 3e22786a01f..9e3bc3e60b1 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -66,6 +66,7 @@ macro_rules! into_diag_arg_for_number { impl IntoDiagArg for $ty { fn into_diag_arg(self) -> DiagArgValue { // Convert to a string if it won't fit into `Number`. + #[allow(irrefutable_let_patterns)] if let Ok(n) = TryInto::::try_into(self) { DiagArgValue::Number(n) } else { diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index b499604df87..5bd7736a3f3 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -28,6 +28,7 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::potential_query_instability)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(bootstrap, feature(min_exhaustive_patterns))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(allocator_api)] @@ -48,7 +49,6 @@ #![feature(iter_from_coroutine)] #![feature(let_chains)] #![feature(macro_metavar_expr)] -#![feature(min_exhaustive_patterns)] #![feature(min_specialization)] #![feature(negative_impls)] #![feature(never_type)] diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index ecc91ab9a31..b2116c51216 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -9,12 +9,12 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(bootstrap, feature(min_exhaustive_patterns))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(assert_matches)] #![feature(iter_intersperse)] #![feature(let_chains)] -#![feature(min_exhaustive_patterns)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] // tidy-alphabetical-end diff --git a/compiler/rustc_transmute/src/layout/nfa.rs b/compiler/rustc_transmute/src/layout/nfa.rs index 0dd26badc88..5db5a8f222d 100644 --- a/compiler/rustc_transmute/src/layout/nfa.rs +++ b/compiler/rustc_transmute/src/layout/nfa.rs @@ -87,6 +87,7 @@ where pub(crate) fn from_tree(tree: Tree) -> Result { Ok(match tree { Tree::Byte(b) => Self::from_byte(b), + #[cfg(bootstrap)] Tree::Def(..) => unreachable!(), Tree::Ref(r) => Self::from_ref(r), Tree::Alt(alts) => { diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index 16dcf76e73e..d37bacc7d35 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -91,6 +91,7 @@ pub trait TypeFoldable: TypeVisitable { fn fold_with>(self, folder: &mut F) -> Self { match self.try_fold_with(folder) { Ok(t) => t, + #[cfg(bootstrap)] Err(e) => match e {}, } } @@ -115,6 +116,7 @@ pub trait TypeSuperFoldable: TypeFoldable { fn super_fold_with>(self, folder: &mut F) -> Self { match self.try_super_fold_with(folder) { Ok(t) => t, + #[cfg(bootstrap)] Err(e) => match e {}, } } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 9d4520d4ee8..07daa32afa8 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -192,6 +192,7 @@ // // Language features: // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(min_exhaustive_patterns))] #![feature(abi_unadjusted)] #![feature(adt_const_params)] #![feature(allow_internal_unsafe)] @@ -225,7 +226,6 @@ #![feature(link_llvm_intrinsics)] #![feature(macro_metavar_expr)] #![feature(marker_trait_attr)] -#![feature(min_exhaustive_patterns)] #![feature(min_specialization)] #![feature(multiple_supertrait_upcastable)] #![feature(must_not_suspend)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 7fc1bc46fef..93a74ef739b 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -272,6 +272,7 @@ // // Language features: // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(min_exhaustive_patterns))] #![feature(alloc_error_handler)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] @@ -299,7 +300,6 @@ #![feature(link_cfg)] #![feature(linkage)] #![feature(macro_metavar_expr_concat)] -#![feature(min_exhaustive_patterns)] #![feature(min_specialization)] #![feature(must_not_suspend)] #![feature(needs_panic_runtime)] -- cgit 1.4.1-3-g733a5