Skip to content

Rustup #6971

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Mar 25, 2021
Merged

Rustup #6971

Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7406c12
Deprecate items that accidentally weren't deprecated
bstrie Feb 14, 2021
f2f2a00
Merge commit '6ed6f1e6a1a8f414ba7e6d9b8222e7e5a1686e42' into clippyup
flip1995 Mar 12, 2021
a189df1
Clippy: HACK! Fix bootstrap error
flip1995 Mar 12, 2021
0ab2bcd
Add fake_read() to clippy
roxelo Feb 25, 2021
1d57c3e
Use `rustc_interface::interface::Config::parse_sess_created` in Clippy
Mar 15, 2021
7926664
Add comments with examples and tests
roxelo Feb 25, 2021
9d5daa6
Fix error after rebase
roxelo Mar 15, 2021
09a9ea6
Update clippy tests
petrochenkov Mar 15, 2021
35e8be7
ast/hir: Rename field-related structures
petrochenkov Mar 15, 2021
e72d283
ast: Reduce size of `ExprKind` by boxing fields of `ExprKind::Struct`
petrochenkov Mar 16, 2021
846d4f0
Auto merge of #82536 - sexxi-goose:handle-patterns-take-2, r=nikomats…
bors Mar 16, 2021
5476382
Rollup merge of #83092 - petrochenkov:qspan, r=estebank
JohnTitor Mar 17, 2021
56138ad
Auto merge of #83188 - petrochenkov:field, r=lcnr
bors Mar 17, 2021
b62694b
Auto merge of #82122 - bstrie:dep4real, r=dtolnay
bors Mar 17, 2021
2c4570c
hir: Preserve used syntax in `TyKind::TraitObject`
petrochenkov Mar 13, 2021
d2f0b27
clippy: stabilize or_patterns lint
mark-i-m Nov 21, 2020
731c98b
update `const_eval_resolve`
lcnr Mar 13, 2021
2bc180e
Auto merge of #79278 - mark-i-m:stabilize-or-pattern, r=nikomatsakis
bors Mar 22, 2021
e06731b
Add has_default to GenericParamDefKind::Const
JulianKnodt Aug 11, 2020
1f5f184
Merge remote-tracking branch 'upstream/master' into rustup
flip1995 Mar 25, 2021
06940fd
Bump nightly version -> 2021-03-25
flip1995 Mar 25, 2021
40e68e5
Bump Clippy Version -> 0.1.53
flip1995 Mar 25, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "clippy"
version = "0.1.52"
version = "0.1.53"
authors = ["The Rust Clippy Developers"]
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
2 changes: 1 addition & 1 deletion clippy_lints/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "clippy_lints"
# begin automatic update
version = "0.1.52"
version = "0.1.53"
# end automatic update
authors = ["The Rust Clippy Developers"]
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
2 changes: 1 addition & 1 deletion clippy_lints/src/attrs.rs
Original file line number Diff line number Diff line change
@@ -564,7 +564,7 @@ fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute) {
// check for `rustfmt_skip` and `rustfmt::skip`
if let Some(skip_item) = &items[1].meta_item();
if skip_item.has_name(sym!(rustfmt_skip)) ||
skip_item.path.segments.last().expect("empty path in attribute").ident.name == sym!(skip);
skip_item.path.segments.last().expect("empty path in attribute").ident.name == sym::skip;
// Only lint outer attributes, because custom inner attributes are unstable
// Tracking issue: https://github.com/rust-lang/rust/issues/54726
if let AttrStyle::Outer = attr.style;
3 changes: 3 additions & 0 deletions clippy_lints/src/escape.rs
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ use rustc_hir::intravisit;
use rustc_hir::{self, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::mir::FakeReadCause;
use rustc_middle::ty::{self, TraitRef, Ty};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span;
@@ -184,6 +185,8 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
}
}
}

fn fake_read(&mut self, _: rustc_typeck::expr_use_visitor::Place<'tcx>, _: FakeReadCause, _: HirId) {}
}

impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
2 changes: 1 addition & 1 deletion clippy_lints/src/inconsistent_struct_constructor.rs
Original file line number Diff line number Diff line change
@@ -120,7 +120,7 @@ impl LateLintPass<'_> for InconsistentStructConstructor {

// Check whether the order of the fields in the constructor is consistent with the order in the
// definition.
fn is_consistent_order<'tcx>(fields: &'tcx [hir::Field<'tcx>], def_order_map: &FxHashMap<Symbol, usize>) -> bool {
fn is_consistent_order<'tcx>(fields: &'tcx [hir::ExprField<'tcx>], def_order_map: &FxHashMap<Symbol, usize>) -> bool {
let mut cur_idx = usize::MIN;
for f in fields {
let next_idx = def_order_map[&f.ident.name];
1 change: 0 additions & 1 deletion clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
@@ -5,7 +5,6 @@
#![feature(drain_filter)]
#![feature(in_band_lifetimes)]
#![feature(once_cell)]
#![feature(or_patterns)]
#![feature(rustc_private)]
#![feature(stmt_expr_attributes)]
#![feature(control_flow_enum)]
2 changes: 1 addition & 1 deletion clippy_lints/src/lifetimes.rs
Original file line number Diff line number Diff line change
@@ -388,7 +388,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
self.nested_elision_site_lts.append(&mut sub_visitor.all_lts());
return;
},
TyKind::TraitObject(bounds, ref lt) => {
TyKind::TraitObject(bounds, ref lt, _) => {
if !lt.is_elided() {
self.unelided_trait_object_lifetime = true;
}
4 changes: 3 additions & 1 deletion clippy_lints/src/loops/mut_range_bound.rs
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ use if_chain::if_chain;
use rustc_hir::{BindingAnnotation, Expr, HirId, Node, PatKind};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::LateContext;
use rustc_middle::ty;
use rustc_middle::{mir::FakeReadCause, ty};
use rustc_span::source_map::Span;
use rustc_typeck::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};

@@ -107,6 +107,8 @@ impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> {
}
}
}

fn fake_read(&mut self, _: rustc_typeck::expr_use_visitor::Place<'tcx>, _: FakeReadCause, _: HirId) {}
}

impl MutatePairDelegate<'_, '_> {
6 changes: 3 additions & 3 deletions clippy_lints/src/manual_non_exhaustive.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::meets_msrv;
use clippy_utils::source::snippet_opt;
use if_chain::if_chain;
use rustc_ast::ast::{Attribute, Item, ItemKind, StructField, Variant, VariantData, VisibilityKind};
use rustc_ast::ast::{Attribute, FieldDef, Item, ItemKind, Variant, VariantData, VisibilityKind};
use rustc_attr as attr;
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
@@ -144,11 +144,11 @@ fn check_manual_non_exhaustive_enum(cx: &EarlyContext<'_>, item: &Item, variants
}

fn check_manual_non_exhaustive_struct(cx: &EarlyContext<'_>, item: &Item, data: &VariantData) {
fn is_private(field: &StructField) -> bool {
fn is_private(field: &FieldDef) -> bool {
matches!(field.vis.kind, VisibilityKind::Inherited)
}

fn is_non_exhaustive_marker(field: &StructField) -> bool {
fn is_non_exhaustive_marker(field: &FieldDef) -> bool {
is_private(field) && field.ty.kind.is_unit() && field.ident.map_or(true, |n| n.as_str().starts_with('_'))
}

2 changes: 1 addition & 1 deletion clippy_lints/src/matches.rs
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@ use rustc_span::source_map::{Span, Spanned};
use rustc_span::sym;
use std::cmp::Ordering;
use std::collections::hash_map::Entry;
use std::collections::Bound;
use std::ops::Bound;

declare_clippy_lint! {
/// **What it does:** Checks for matches with a single arm where an `if let`
1 change: 1 addition & 0 deletions clippy_lints/src/methods/or_fun_call.rs
Original file line number Diff line number Diff line change
@@ -155,6 +155,7 @@ pub(super) fn check<'tcx>(
}
}
}

if args.len() == 2 {
match args[1].kind {
hir::ExprKind::Call(ref fun, ref or_args) => {
2 changes: 1 addition & 1 deletion clippy_lints/src/missing_doc.rs
Original file line number Diff line number Diff line change
@@ -188,7 +188,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
self.check_missing_docs_attrs(cx, attrs, impl_item.span, article, desc);
}

fn check_struct_field(&mut self, cx: &LateContext<'tcx>, sf: &'tcx hir::StructField<'_>) {
fn check_field_def(&mut self, cx: &LateContext<'tcx>, sf: &'tcx hir::FieldDef<'_>) {
if !sf.is_positional() {
let attrs = cx.tcx.hir().attrs(sf.hir_id);
self.check_missing_docs_attrs(cx, attrs, sf.span, "a", "struct field");
3 changes: 3 additions & 0 deletions clippy_lints/src/needless_pass_by_value.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ use rustc_hir::intravisit::FnKind;
use rustc_hir::{BindingAnnotation, Body, FnDecl, GenericArg, HirId, Impl, ItemKind, Node, PatKind, QPath, TyKind};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::mir::FakeReadCause;
use rustc_middle::ty::{self, TypeFoldable};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::kw;
@@ -333,4 +334,6 @@ impl<'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt {
fn borrow(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) {}

fn mutate(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId) {}

fn fake_read(&mut self, _: rustc_typeck::expr_use_visitor::Place<'tcx>, _: FakeReadCause, _: HirId) {}
}
12 changes: 9 additions & 3 deletions clippy_lints/src/non_copy_const.rs
Original file line number Diff line number Diff line change
@@ -179,9 +179,15 @@ fn is_value_unfrozen_poly<'tcx>(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<
fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool {
let substs = cx.typeck_results().node_substs(hir_id);

let result = cx
.tcx
.const_eval_resolve(cx.param_env, ty::WithOptConstParam::unknown(def_id), substs, None, None);
let result = cx.tcx.const_eval_resolve(
cx.param_env,
ty::Unevaluated {
def: ty::WithOptConstParam::unknown(def_id),
substs,
promoted: None,
},
None,
);
is_value_unfrozen_raw(cx, result, ty)
}

4 changes: 2 additions & 2 deletions clippy_lints/src/pattern_type_mismatch.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::last_path_segment;
use rustc_hir::{
intravisit, Body, Expr, ExprKind, FieldPat, FnDecl, HirId, LocalSource, MatchSource, Mutability, Pat, PatKind,
intravisit, Body, Expr, ExprKind, FnDecl, HirId, LocalSource, MatchSource, Mutability, Pat, PatField, PatKind,
QPath, Stmt, StmtKind,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -282,7 +282,7 @@ where

fn find_first_mismatch_in_struct<'tcx>(
cx: &LateContext<'tcx>,
field_pats: &[FieldPat<'_>],
field_pats: &[PatField<'_>],
field_defs: &[FieldDef],
substs_ref: SubstsRef<'tcx>,
) -> Option<(Span, Mutability, Level)> {
4 changes: 2 additions & 2 deletions clippy_lints/src/redundant_field_names.rs
Original file line number Diff line number Diff line change
@@ -59,8 +59,8 @@ impl EarlyLintPass for RedundantFieldNames {
if in_external_macro(cx.sess, expr.span) {
return;
}
if let ExprKind::Struct(_, ref fields, _) = expr.kind {
for field in fields {
if let ExprKind::Struct(ref se) = expr.kind {
for field in &se.fields {
if field.is_shorthand {
continue;
}
2 changes: 1 addition & 1 deletion clippy_lints/src/suspicious_operation_groupings.rs
Original file line number Diff line number Diff line change
@@ -565,7 +565,7 @@ fn ident_difference_expr_with_base_location(
| (Try(_), Try(_))
| (Paren(_), Paren(_))
| (Repeat(_, _), Repeat(_, _))
| (Struct(_, _, _), Struct(_, _, _))
| (Struct(_), Struct(_))
| (MacCall(_), MacCall(_))
| (LlvmInlineAsm(_), LlvmInlineAsm(_))
| (InlineAsm(_), InlineAsm(_))
4 changes: 2 additions & 2 deletions clippy_lints/src/types/borrowed_box.rs
Original file line number Diff line number Diff line change
@@ -50,7 +50,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
// Originally reported as the issue #3128.
let inner_snippet = snippet(cx, inner.span, "..");
let suggestion = match &inner.kind {
TyKind::TraitObject(bounds, lt_bound) if bounds.len() > 1 || !lt_bound.is_elided() => {
TyKind::TraitObject(bounds, lt_bound, _) if bounds.len() > 1 || !lt_bound.is_elided() => {
format!("&{}({})", ltopt, &inner_snippet)
},
TyKind::Path(qpath)
@@ -86,7 +86,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
// Returns true if given type is `Any` trait.
fn is_any_trait(t: &hir::Ty<'_>) -> bool {
if_chain! {
if let TyKind::TraitObject(ref traits, _) = t.kind;
if let TyKind::TraitObject(ref traits, ..) = t.kind;
if !traits.is_empty();
// Only Send/Sync can be used as additional traits, so it is enough to
// check only the first trait.
6 changes: 3 additions & 3 deletions clippy_lints/src/types/mod.rs
Original file line number Diff line number Diff line change
@@ -268,7 +268,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
self.check_fn_decl(cx, decl);
}

fn check_struct_field(&mut self, cx: &LateContext<'_>, field: &hir::StructField<'_>) {
fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) {
self.check_ty(cx, &field.ty, false);
}

@@ -434,7 +434,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeComplexity {
self.check_fndecl(cx, decl);
}

fn check_struct_field(&mut self, cx: &LateContext<'tcx>, field: &'tcx hir::StructField<'_>) {
fn check_field_def(&mut self, cx: &LateContext<'tcx>, field: &'tcx hir::FieldDef<'_>) {
// enum variants are also struct fields now
self.check_type(cx, &field.ty);
}
@@ -524,7 +524,7 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
// function types bring a lot of overhead
TyKind::BareFn(ref bare) if bare.abi == Abi::Rust => (50 * self.nest, 1),

TyKind::TraitObject(ref param_bounds, _) => {
TyKind::TraitObject(ref param_bounds, _, _) => {
let has_lifetime_parameters = param_bounds.iter().any(|bound| {
bound
.bound_generic_params
7 changes: 1 addition & 6 deletions clippy_lints/src/unnested_or_patterns.rs
Original file line number Diff line number Diff line change
@@ -73,11 +73,6 @@ impl EarlyLintPass for UnnestedOrPatterns {
}

fn lint_unnested_or_patterns(cx: &EarlyContext<'_>, pat: &Pat) {
if !cx.sess.features_untracked().or_patterns {
// Do not suggest nesting the patterns if the feature `or_patterns` is not enabled.
return;
}

if let Ident(.., None) | Lit(_) | Wild | Path(..) | Range(..) | Rest | MacCall(_) = pat.kind {
// This is a leaf pattern, so cloning is unprofitable.
return;
@@ -277,7 +272,7 @@ fn transform_with_focus_on_idx(alternatives: &mut Vec<P<Pat>>, focus_idx: usize)
/// and check that all `fp_i` where `i ∈ ((0...n) \ k)` between two patterns are equal.
fn extend_with_struct_pat(
path1: &ast::Path,
fps1: &mut Vec<ast::FieldPat>,
fps1: &mut Vec<ast::PatField>,
rest1: bool,
start: usize,
alternatives: &mut Vec<P<Pat>>,
4 changes: 2 additions & 2 deletions clippy_lints/src/utils/author.rs
Original file line number Diff line number Diff line change
@@ -101,12 +101,12 @@ impl<'tcx> LateLintPass<'tcx> for Author {
done();
}

fn check_struct_field(&mut self, cx: &LateContext<'tcx>, field: &'tcx hir::StructField<'_>) {
fn check_field_def(&mut self, cx: &LateContext<'tcx>, field: &'tcx hir::FieldDef<'_>) {
if !has_attr(cx, field.hir_id) {
return;
}
prelude();
PrintVisitor::new("field").visit_struct_field(field);
PrintVisitor::new("field").visit_field_def(field);
done();
}

4 changes: 2 additions & 2 deletions clippy_lints/src/utils/inspector.rs
Original file line number Diff line number Diff line change
@@ -80,8 +80,8 @@ impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector {
// }
// }
//
// fn check_struct_field(&mut self, cx: &LateContext<'tcx>, field: &'tcx
// hir::StructField) {
// fn check_field_def(&mut self, cx: &LateContext<'tcx>, field: &'tcx
// hir::FieldDef) {
// if !has_attr(&field.attrs) {
// return;
// }
2 changes: 1 addition & 1 deletion clippy_utils/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "clippy_utils"
version = "0.1.52"
version = "0.1.53"
authors = ["The Rust Clippy Developers"]
edition = "2018"
publish = false
20 changes: 11 additions & 9 deletions clippy_utils/src/ast_utils.rs
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@ pub fn eq_range_end(l: &RangeEnd, r: &RangeEnd) -> bool {
}
}

pub fn eq_field_pat(l: &FieldPat, r: &FieldPat) -> bool {
pub fn eq_field_pat(l: &PatField, r: &PatField) -> bool {
l.is_placeholder == r.is_placeholder
&& eq_id(l.ident, r.ident)
&& eq_pat(&l.pat, &r.pat)
@@ -168,14 +168,16 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
(AddrOf(lbk, lm, le), AddrOf(rbk, rm, re)) => lbk == rbk && lm == rm && eq_expr(le, re),
(Path(lq, lp), Path(rq, rp)) => both(lq, rq, |l, r| eq_qself(l, r)) && eq_path(lp, rp),
(MacCall(l), MacCall(r)) => eq_mac_call(l, r),
(Struct(lp, lfs, lb), Struct(rp, rfs, rb)) => {
eq_path(lp, rp) && eq_struct_rest(lb, rb) && unordered_over(lfs, rfs, |l, r| eq_field(l, r))
(Struct(lse), Struct(rse)) => {
eq_path(&lse.path, &rse.path)
&& eq_struct_rest(&lse.rest, &rse.rest)
&& unordered_over(&lse.fields, &rse.fields, |l, r| eq_field(l, r))
},
_ => false,
}
}

pub fn eq_field(l: &Field, r: &Field) -> bool {
pub fn eq_field(l: &ExprField, r: &ExprField) -> bool {
l.is_placeholder == r.is_placeholder
&& eq_id(l.ident, r.ident)
&& eq_expr(&l.expr, &r.expr)
@@ -359,7 +361,7 @@ pub fn eq_variant_data(l: &VariantData, r: &VariantData) -> bool {
}
}

pub fn eq_struct_field(l: &StructField, r: &StructField) -> bool {
pub fn eq_struct_field(l: &FieldDef, r: &FieldDef) -> bool {
l.is_placeholder == r.is_placeholder
&& over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r))
&& eq_vis(&l.vis, &r.vis)
@@ -406,6 +408,10 @@ pub fn eq_use_tree(l: &UseTree, r: &UseTree) -> bool {
eq_path(&l.prefix, &r.prefix) && eq_use_tree_kind(&l.kind, &r.kind)
}

pub fn eq_anon_const(l: &AnonConst, r: &AnonConst) -> bool {
eq_expr(&l.value, &r.value)
}

pub fn eq_use_tree_kind(l: &UseTreeKind, r: &UseTreeKind) -> bool {
use UseTreeKind::*;
match (l, r) {
@@ -416,10 +422,6 @@ pub fn eq_use_tree_kind(l: &UseTreeKind, r: &UseTreeKind) -> bool {
}
}

pub fn eq_anon_const(l: &AnonConst, r: &AnonConst) -> bool {
eq_expr(&l.value, &r.value)
}

pub fn eq_defaultness(l: Defaultness, r: Defaultness) -> bool {
matches!(
(l, r),
8 changes: 5 additions & 3 deletions clippy_utils/src/consts.rs
Original file line number Diff line number Diff line change
@@ -341,9 +341,11 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
.tcx
.const_eval_resolve(
self.param_env,
ty::WithOptConstParam::unknown(def_id),
substs,
None,
ty::Unevaluated {
def: ty::WithOptConstParam::unknown(def_id),
substs,
promoted: None,
},
None,
)
.ok()
2 changes: 1 addition & 1 deletion clippy_utils/src/higher.rs
Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@ pub struct Range<'a> {
pub fn range<'a>(expr: &'a hir::Expr<'_>) -> Option<Range<'a>> {
/// Finds the field named `name` in the field. Always return `Some` for
/// convenience.
fn get_field<'c>(name: &str, fields: &'c [hir::Field<'_>]) -> Option<&'c hir::Expr<'c>> {
fn get_field<'c>(name: &str, fields: &'c [hir::ExprField<'_>]) -> Option<&'c hir::Expr<'c>> {
let expr = &fields.iter().find(|field| field.ident.name.as_str() == name)?.expr;

Some(expr)
Loading