mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
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,
|
FakeReadCause, Local, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
|
||||||
ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
|
ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::{self, suggest_constraining_type_param, Instance, Ty};
|
use rustc_middle::ty::{self, suggest_constraining_type_param, Ty, TypeFoldable};
|
||||||
use rustc_span::{source_map::DesugaringKind, symbol::sym, Span};
|
use rustc_span::source_map::DesugaringKind;
|
||||||
|
use rustc_span::symbol::sym;
|
||||||
|
use rustc_span::Span;
|
||||||
|
|
||||||
use crate::dataflow::drop_flag_effects;
|
use crate::dataflow::drop_flag_effects;
|
||||||
use crate::dataflow::indexes::{MoveOutIndex, MovePathIndex};
|
use crate::dataflow::indexes::{MoveOutIndex, MovePathIndex};
|
||||||
use crate::util::borrowck_errors;
|
use crate::util::borrowck_errors;
|
||||||
|
|
||||||
use crate::borrow_check::{
|
use crate::borrow_check::{
|
||||||
borrow_set::BorrowData, prefixes::IsPrefixOf, InitializationRequiringAction, MirBorrowckCtxt,
|
borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf,
|
||||||
PrefixSet, WriteKind,
|
InitializationRequiringAction, MirBorrowckCtxt, PrefixSet, WriteKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -1267,6 +1269,29 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
|
|
||||||
if return_span != borrow_span {
|
if return_span != borrow_span {
|
||||||
err.span_label(borrow_span, note);
|
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)
|
Some(err)
|
||||||
|
@ -93,6 +93,7 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
|
|||||||
message = "`{Self}` is not an iterator"
|
message = "`{Self}` is not an iterator"
|
||||||
)]
|
)]
|
||||||
#[doc(spotlight)]
|
#[doc(spotlight)]
|
||||||
|
#[rustc_diagnostic_item = "Iterator"]
|
||||||
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
||||||
pub trait Iterator {
|
pub trait Iterator {
|
||||||
/// The type of the elements being iterated over.
|
/// 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
|
| | ------------------------------ temporary value created here
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_____^ returns a value referencing data owned by the current function
|
| |_____^ returns a value referencing data owned by the current function
|
||||||
|
|
|
||||||
|
= help: use `.collect()` to allocate the iterator
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user