Skip to content

Commit

Permalink
While let suggestion will work for closure
Browse files Browse the repository at this point in the history
  • Loading branch information
chenyukang committed Jul 11, 2023
1 parent d8899c5 commit 9aed969
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 38 deletions.
77 changes: 39 additions & 38 deletions compiler/rustc_infer/src/infer/error_reporting/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,52 +464,53 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
span: Span,
) -> Option<TypeErrorAdditionalDiags> {
let hir = self.tcx.hir();
if let Some(node) = self.tcx.hir().find_by_def_id(cause.body_id) &&
let hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(_sig, _, body_id), ..
}) = node {
let body = hir.body(*body_id);

/// Find the if expression with given span
struct IfVisitor {
pub result: bool,
pub found_if: bool,
pub err_span: Span,
}
if let Some(body_id) = self.tcx.hir().maybe_body_owned_by(cause.body_id) {
let body = hir.body(body_id);

/// Find the if expression with given span
struct IfVisitor {
pub result: bool,
pub found_if: bool,
pub err_span: Span,
}

impl<'v> Visitor<'v> for IfVisitor {
fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
if self.result { return; }
match ex.kind {
hir::ExprKind::If(cond, _, _) => {
self.found_if = true;
walk_expr(self, cond);
self.found_if = false;
impl<'v> Visitor<'v> for IfVisitor {
fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
if self.result {
return;
}
match ex.kind {
hir::ExprKind::If(cond, _, _) => {
self.found_if = true;
walk_expr(self, cond);
self.found_if = false;
}
_ => walk_expr(self, ex),
}
_ => walk_expr(self, ex),
}
}

fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) {
if let hir::StmtKind::Local(hir::Local {
span, pat: hir::Pat{..}, ty: None, init: Some(_), ..
}) = &ex.kind
&& self.found_if
&& span.eq(&self.err_span) {
self.result = true;
fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) {
if let hir::StmtKind::Local(hir::Local {
span, pat: hir::Pat{..}, ty: None, init: Some(_), ..
}) = &ex.kind
&& self.found_if
&& span.eq(&self.err_span) {
self.result = true;
}
walk_stmt(self, ex);
}
walk_stmt(self, ex);
}

fn visit_body(&mut self, body: &'v hir::Body<'v>) {
hir::intravisit::walk_body(self, body);
fn visit_body(&mut self, body: &'v hir::Body<'v>) {
hir::intravisit::walk_body(self, body);
}
}
}

let mut visitor = IfVisitor { err_span: span, found_if: false, result: false };
visitor.visit_body(&body);
if visitor.result {
return Some(TypeErrorAdditionalDiags::AddLetForLetChains{span: span.shrink_to_lo()});
let mut visitor = IfVisitor { err_span: span, found_if: false, result: false };
visitor.visit_body(&body);
if visitor.result {
return Some(TypeErrorAdditionalDiags::AddLetForLetChains {
span: span.shrink_to_lo(),
});
}
}
None
Expand Down
4 changes: 4 additions & 0 deletions tests/ui/inference/issue-113354.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//run-rustfix
fn main() {
let _ = || { while let Some(_) = Some(1) { } }; //~ ERROR mismatched types
}
4 changes: 4 additions & 0 deletions tests/ui/inference/issue-113354.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//run-rustfix
fn main() {
let _ = || { while Some(_) = Some(1) { } }; //~ ERROR mismatched types
}
14 changes: 14 additions & 0 deletions tests/ui/inference/issue-113354.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0308]: mismatched types
--> $DIR/issue-113354.rs:3:24
|
LL | let _ = || { while Some(_) = Some(1) { } };
| ^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
|
help: consider adding `let`
|
LL | let _ = || { while let Some(_) = Some(1) { } };
| +++

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

0 comments on commit 9aed969

Please sign in to comment.