Skip to content

Commit c748a64

Browse files
Handle fields on things other than self
1 parent 4862a84 commit c748a64

2 files changed

Lines changed: 26 additions & 2 deletions

File tree

clippy_lints/src/iter_missing_exact_size.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ use clippy_utils::paths::{PathNS, lookup_path_str};
33
use clippy_utils::sym;
44
use clippy_utils::ty::{get_field_by_name, implements_trait, ty_from_hir_ty};
55
use rustc_errors::MultiSpan;
6-
use rustc_hir::{Body, ExprKind, Impl, ImplItemKind, Item, ItemKind, OwnerId, OwnerNode};
6+
use rustc_hir::{Body, ExprKind, Impl, ImplItemKind, Item, ItemKind, OwnerId, OwnerNode, QPath};
77
use rustc_lint::{LateContext, LateLintPass};
88
use rustc_session::impl_lint_pass;
99
use rustc_span::def_id::DefId;
1010
use rustc_span::sym as rustc_sym;
11+
use rustc_span::symbol::kw;
1112

1213
declare_clippy_lint! {
1314
/// ### What it does
@@ -151,7 +152,10 @@ impl<'tcx> LateLintPass<'tcx> for IterMissingExactSize {
151152
&& let Some(trailing_expr) = block.expr
152153
&& let ExprKind::MethodCall(method_name, receiver, args, _) = trailing_expr.kind
153154
&& method_name.ident.name == sym::size_hint
154-
&& let ExprKind::Field(_object, field_name) = receiver.kind
155+
&& let ExprKind::Field(object, field_name) = receiver.kind
156+
&& let ExprKind::Path(QPath::Resolved(_, object_path)) = object.kind
157+
&& let [path_segment] = object_path.segments
158+
&& path_segment.ident.name == kw::SelfLower
155159
&& args.is_empty()
156160
{
157161
// The function body is just `self.{field}.size_hint()`, check

tests/ui/iter_missing_exact_size.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,23 @@ impl Iterator for MyCollectionIter {
7272
}
7373
}
7474

75+
// Delegates to an ExactSizeIterator but not an object field
76+
struct EmptyWithHint {}
77+
78+
fn range_provider() -> (Range<usize>,) {
79+
(0..5,)
80+
}
81+
82+
impl Iterator for EmptyWithHint {
83+
type Item = String;
84+
fn next(&mut self) -> Option<Self::Item> {
85+
None
86+
}
87+
fn size_hint(&self) -> (usize, Option<usize>) {
88+
range_provider().0.size_hint()
89+
}
90+
}
91+
7592
fn main() {
7693
let repeater = StringRepeater1 {
7794
original: "Foo".to_string(),
@@ -99,4 +116,7 @@ fn main() {
99116
for value in collection {
100117
println!("{value}");
101118
}
119+
120+
let mut empty_provider = EmptyWithHint {};
121+
assert_eq!(None, empty_provider.next());
102122
}

0 commit comments

Comments
 (0)