Modify find_expr
from Span
to better account for closures
Start pointing to where bindings were declared when they are captured in closures: ``` error[E0597]: `x` does not live long enough --> $DIR/suggest-return-closure.rs:23:9 | LL | let x = String::new(); | - binding `x` declared here ... LL | |c| { | --- value captured here LL | x.push(c); | ^ borrowed value does not live long enough ... LL | } | -- borrow later used here | | | `x` dropped here while still borrowed ``` Suggest cloning in more cases involving closures: ``` error[E0507]: cannot move out of `foo` in pattern guard --> $DIR/issue-27282-move-ref-mut-into-guard.rs:11:19 | LL | if { (|| { let mut bar = foo; bar.take() })(); false } => {}, | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait | | | `foo` is moved here | = note: variables bound in patterns cannot be moved from until after the end of the pattern guard help: consider cloning the value if the performance cost is acceptable | LL | if { (|| { let mut bar = foo.clone(); bar.take() })(); false } => {}, | ++++++++ ```
This commit is contained in:
parent
ef8b9dcf23
commit
4aba2c55e6
31 changed files with 202 additions and 31 deletions
|
@ -50,15 +50,22 @@ pub struct FindExprBySpan<'hir> {
|
|||
pub span: Span,
|
||||
pub result: Option<&'hir hir::Expr<'hir>>,
|
||||
pub ty_result: Option<&'hir hir::Ty<'hir>>,
|
||||
pub tcx: TyCtxt<'hir>,
|
||||
}
|
||||
|
||||
impl<'hir> FindExprBySpan<'hir> {
|
||||
pub fn new(span: Span) -> Self {
|
||||
Self { span, result: None, ty_result: None }
|
||||
pub fn new(span: Span, tcx: TyCtxt<'hir>) -> Self {
|
||||
Self { span, result: None, ty_result: None, tcx }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'v> Visitor<'v> for FindExprBySpan<'v> {
|
||||
type NestedFilter = rustc_middle::hir::nested_filter::OnlyBodies;
|
||||
|
||||
fn nested_visit_map(&mut self) -> Self::Map {
|
||||
self.tcx.hir()
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
|
||||
if self.span == ex.span {
|
||||
self.result = Some(ex);
|
||||
|
|
|
@ -901,7 +901,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
// Remove all the desugaring and macro contexts.
|
||||
span.remove_mark();
|
||||
}
|
||||
let mut expr_finder = FindExprBySpan::new(span);
|
||||
let mut expr_finder = FindExprBySpan::new(span, self.tcx);
|
||||
let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else {
|
||||
return;
|
||||
};
|
||||
|
@ -1367,7 +1367,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
return false;
|
||||
};
|
||||
let body = self.tcx.hir().body(body_id);
|
||||
let mut expr_finder = FindExprBySpan::new(span);
|
||||
let mut expr_finder = FindExprBySpan::new(span, self.tcx);
|
||||
expr_finder.visit_expr(body.value);
|
||||
let Some(expr) = expr_finder.result else {
|
||||
return false;
|
||||
|
@ -1469,7 +1469,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
// Remove all the hir desugaring contexts while maintaining the macro contexts.
|
||||
span.remove_mark();
|
||||
}
|
||||
let mut expr_finder = super::FindExprBySpan::new(span);
|
||||
let mut expr_finder = super::FindExprBySpan::new(span, self.tcx);
|
||||
let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else {
|
||||
return false;
|
||||
};
|
||||
|
|
|
@ -2457,7 +2457,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
&& let Some(body_id) =
|
||||
self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id)
|
||||
{
|
||||
let mut expr_finder = FindExprBySpan::new(span);
|
||||
let mut expr_finder = FindExprBySpan::new(span, self.tcx);
|
||||
expr_finder.visit_expr(self.tcx.hir().body(body_id).value);
|
||||
|
||||
if let Some(hir::Expr {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue