Add suggestion for iterators in iterators
This commit is contained in:
parent
fe1bf8e05c
commit
a3db47ab6c
@ -10,16 +10,18 @@ use rustc_middle::mir::{
|
||||
FakeReadCause, Local, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
|
||||
ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
|
||||
};
|
||||
use rustc_middle::ty::{self, suggest_constraining_type_param, Instance, Ty};
|
||||
use rustc_span::{source_map::DesugaringKind, symbol::sym, Span};
|
||||
use rustc_middle::ty::{self, suggest_constraining_type_param, Ty, TypeFoldable};
|
||||
use rustc_span::source_map::DesugaringKind;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
|
||||
use crate::dataflow::drop_flag_effects;
|
||||
use crate::dataflow::indexes::{MoveOutIndex, MovePathIndex};
|
||||
use crate::util::borrowck_errors;
|
||||
|
||||
use crate::borrow_check::{
|
||||
borrow_set::BorrowData, prefixes::IsPrefixOf, InitializationRequiringAction, MirBorrowckCtxt,
|
||||
PrefixSet, WriteKind,
|
||||
borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf,
|
||||
InitializationRequiringAction, MirBorrowckCtxt, PrefixSet, WriteKind,
|
||||
};
|
||||
|
||||
use super::{
|
||||
@ -1267,6 +1269,29 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
|
||||
if return_span != borrow_span {
|
||||
err.span_label(borrow_span, note);
|
||||
|
||||
let tcx = self.infcx.tcx;
|
||||
let ty_params = ty::List::empty();
|
||||
|
||||
let return_ty = self.regioncx.universal_regions().unnormalized_output_ty;
|
||||
let return_ty = tcx.erase_regions(return_ty);
|
||||
|
||||
// to avoid panics
|
||||
if !return_ty.has_infer_types() {
|
||||
if let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator) {
|
||||
if tcx.type_implements_trait((iter_trait, return_ty, ty_params, self.param_env))
|
||||
{
|
||||
if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(return_span) {
|
||||
err.span_suggestion_hidden(
|
||||
return_span,
|
||||
"use `.collect()` to allocate the iterator",
|
||||
format!("{}{}", snippet, ".collect::<Vec<_>>()"),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(err)
|
||||
|
@ -93,6 +93,7 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
|
||||
message = "`{Self}` is not an iterator"
|
||||
)]
|
||||
#[doc(spotlight)]
|
||||
#[rustc_diagnostic_item = "Iterator"]
|
||||
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
||||
pub trait Iterator {
|
||||
/// The type of the elements being iterated over.
|
||||
|
8
src/test/ui/issues/issue-81584.fixed
Normal file
8
src/test/ui/issues/issue-81584.fixed
Normal file
@ -0,0 +1,8 @@
|
||||
// run-rustfix
|
||||
fn main() {
|
||||
let _ = vec![vec![0, 1], vec![2]]
|
||||
.into_iter()
|
||||
.map(|y| y.iter().map(|x| x + 1).collect::<Vec<_>>())
|
||||
//~^ ERROR cannot return value referencing function parameter `y`
|
||||
.collect::<Vec<_>>();
|
||||
}
|
8
src/test/ui/issues/issue-81584.rs
Normal file
8
src/test/ui/issues/issue-81584.rs
Normal file
@ -0,0 +1,8 @@
|
||||
// run-rustfix
|
||||
fn main() {
|
||||
let _ = vec![vec![0, 1], vec![2]]
|
||||
.into_iter()
|
||||
.map(|y| y.iter().map(|x| x + 1))
|
||||
//~^ ERROR cannot return value referencing function parameter `y`
|
||||
.collect::<Vec<_>>();
|
||||
}
|
14
src/test/ui/issues/issue-81584.stderr
Normal file
14
src/test/ui/issues/issue-81584.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error[E0515]: cannot return value referencing function parameter `y`
|
||||
--> $DIR/issue-81584.rs:5:22
|
||||
|
|
||||
LL | .map(|y| y.iter().map(|x| x + 1))
|
||||
| -^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| returns a value referencing data owned by the current function
|
||||
| `y` is borrowed here
|
||||
|
|
||||
= help: use `.collect()` to allocate the iterator
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0515`.
|
@ -40,6 +40,8 @@ LL | | statefn: &id(state1 as StateMachineFunc)
|
||||
| | ------------------------------ temporary value created here
|
||||
LL | | }
|
||||
| |_____^ returns a value referencing data owned by the current function
|
||||
|
|
||||
= help: use `.collect()` to allocate the iterator
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user