Skip to content

Commit c8ed5c5

Browse files
committed
Fix the issue of invalid suggestion for a reference of iterator
1 parent 0c81f94 commit c8ed5c5

File tree

4 files changed

+91
-1
lines changed

4 files changed

+91
-1
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1284,6 +1284,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
12841284
if self.in_move_closure(expr) {
12851285
return false;
12861286
}
1287+
12871288
// Try to find predicates on *generic params* that would allow copying `ty`
12881289
let mut suggestion =
12891290
if let Some(symbol) = tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) {
@@ -1312,6 +1313,14 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
13121313
}
13131314
}
13141315
}
1316+
1317+
// Don't suggest cloning the result of a `clone` call.
1318+
if let hir::ExprKind::MethodCall(segment, _, _, _) = inner_expr.kind
1319+
&& segment.ident.name == sym::clone
1320+
{
1321+
return false;
1322+
};
1323+
13151324
// Cloning the raw pointer doesn't make sense in some cases and would cause a type mismatch error. (see #126863)
13161325
if inner_expr.span.lo() != expr.span.lo() && !is_raw_ptr {
13171326
// Remove "(*" or "(&"

compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
466466
&& let Some(arg_ty) = typeck_results.expr_ty_adjusted_opt(expr)
467467
{
468468
// Suggest dereferencing the argument to a function/method call if possible
469-
470469
let mut real_trait_pred = trait_pred;
471470
while let Some((parent_code, parent_trait_pred)) = code.parent() {
472471
code = parent_code;
@@ -553,6 +552,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
553552
);
554553
if self.predicate_may_hold(&obligation)
555554
&& self.predicate_must_hold_modulo_regions(&sized_obligation)
555+
// Do not suggest * if it is already a reference,
556+
// will suggest removing the borrow instead in that case.
557+
&& !matches!(expr.kind, hir::ExprKind::AddrOf(..))
556558
{
557559
let call_node = self.tcx.hir_node(*call_hir_id);
558560
let msg = "consider dereferencing here";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
fn main() {
2+
let fields = vec![1];
3+
let variant = vec![2];
4+
5+
// should not suggest `*&variant.iter()`
6+
for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) {
7+
//~^ ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
8+
//~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
9+
eprintln!("{} {}", src, dest);
10+
}
11+
12+
// don't suggest add `variant.iter().clone().clone()`
13+
for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) {
14+
//~^ ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
15+
//~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
16+
eprintln!("{} {}", src, dest);
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator
2+
--> $DIR/invalid-suggest-deref-issue-127590.rs:6:54
3+
|
4+
LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) {
5+
| -------------- ^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`, which is required by `&std::slice::Iter<'_, {integer}>: IntoIterator`
10+
= note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator`
11+
note: required by a bound in `std::iter::zip`
12+
--> $SRC_DIR/core/src/iter/adapters/zip.rs:LL:COL
13+
help: consider removing the leading `&`-reference
14+
|
15+
LL - for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) {
16+
LL + for (src, dest) in std::iter::zip(fields.iter(), variant.iter()) {
17+
|
18+
19+
error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator
20+
--> $DIR/invalid-suggest-deref-issue-127590.rs:6:24
21+
|
22+
LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) {
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator
24+
|
25+
= help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`, which is required by `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>: IntoIterator`
26+
= help: the trait `Iterator` is implemented for `std::slice::Iter<'a, T>`
27+
= note: required for `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>` to implement `Iterator`
28+
= note: required for `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
29+
30+
error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator
31+
--> $DIR/invalid-suggest-deref-issue-127590.rs:13:54
32+
|
33+
LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) {
34+
| -------------- ^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator
35+
| |
36+
| required by a bound introduced by this call
37+
|
38+
= help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`, which is required by `&std::slice::Iter<'_, {integer}>: IntoIterator`
39+
= note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator`
40+
note: required by a bound in `std::iter::zip`
41+
--> $SRC_DIR/core/src/iter/adapters/zip.rs:LL:COL
42+
help: consider removing the leading `&`-reference
43+
|
44+
LL - for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) {
45+
LL + for (src, dest) in std::iter::zip(fields.iter(), variant.iter().clone()) {
46+
|
47+
48+
error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator
49+
--> $DIR/invalid-suggest-deref-issue-127590.rs:13:24
50+
|
51+
LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) {
52+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator
53+
|
54+
= help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`, which is required by `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>: IntoIterator`
55+
= help: the trait `Iterator` is implemented for `std::slice::Iter<'a, T>`
56+
= note: required for `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>` to implement `Iterator`
57+
= note: required for `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
58+
59+
error: aborting due to 4 previous errors
60+
61+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)