use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::in_macro;
use clippy_utils::source::snippet;
use if_chain::if_chain;
use rustc_data_structures::fx::FxHashMap;
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::Symbol;
+use std::fmt::Write as _;
declare_clippy_lint! {
- /// **What it does:** Checks for struct constructors where all fields are shorthand and
+ /// ### What it does
+ /// Checks for struct constructors where all fields are shorthand and
/// the order of the field init shorthand in the constructor is inconsistent
/// with the order in the struct definition.
///
- /// **Why is this bad?** Since the order of fields in a constructor doesn't affect the
+ /// ### Why is this bad?
+ /// Since the order of fields in a constructor doesn't affect the
/// resulted instance as the below example indicates,
///
/// ```rust
///
/// inconsistent order can be confusing and decreases readability and consistency.
///
- /// **Known problems:** None.
- ///
- /// **Example:**
- ///
+ /// ### Example
/// ```rust
/// struct Foo {
/// x: i32,
/// # let y = 2;
/// Foo { x, y };
/// ```
+ #[clippy::version = "1.52.0"]
pub INCONSISTENT_STRUCT_CONSTRUCTOR,
pedantic,
"the order of the field init shorthand is inconsistent with the order in the struct definition"
declare_lint_pass!(InconsistentStructConstructor => [INCONSISTENT_STRUCT_CONSTRUCTOR]);
-impl LateLintPass<'_> for InconsistentStructConstructor {
+impl<'tcx> LateLintPass<'tcx> for InconsistentStructConstructor {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
if_chain! {
- if !in_macro(expr.span);
+ if !expr.span.from_expansion();
if let ExprKind::Struct(qpath, fields, base) = expr.kind;
let ty = cx.typeck_results().expr_ty(expr);
if let Some(adt_def) = ty.ty_adt_def();
if adt_def.is_struct();
- if let Some(variant) = adt_def.variants.iter().next();
+ if let Some(variant) = adt_def.variants().iter().next();
if fields.iter().all(|f| f.is_shorthand);
then {
let mut def_order_map = FxHashMap::default();
for (idx, field) in variant.fields.iter().enumerate() {
- def_order_map.insert(field.ident.name, idx);
+ def_order_map.insert(field.name, idx);
}
if is_consistent_order(fields, &def_order_map) {
let mut fields_snippet = String::new();
let (last_ident, idents) = ordered_fields.split_last().unwrap();
for ident in idents {
- fields_snippet.push_str(&format!("{}, ", ident));
+ let _ = write!(fields_snippet, "{}, ", ident);
}
fields_snippet.push_str(&last_ident.to_string());