Remove this semicolon

This commit is contained in:
ivan770 2020-12-08 20:47:20 +02:00
parent e2e6b709e6
commit cb66bb8ff9
No known key found for this signature in database
GPG key ID: D8C4BD5AE4D9CC4D
5 changed files with 74 additions and 8 deletions

View file

@ -2,7 +2,7 @@
use std::sync::Arc;
use hir_def::{path::path, resolver::HasResolver, AdtId, DefWithBodyId};
use hir_def::{AdtId, DefWithBodyId, expr::Statement, path::path, resolver::HasResolver};
use hir_expand::diagnostics::DiagnosticSink;
use rustc_hash::FxHashSet;
use syntax::{ast, AstPtr};
@ -23,6 +23,8 @@ pub(crate) use hir_def::{
LocalFieldId, VariantId,
};
use super::RemoveThisSemicolon;
pub(super) struct ExprValidator<'a, 'b: 'a> {
owner: DefWithBodyId,
infer: Arc<InferenceResult>,
@ -78,6 +80,12 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
let body_expr = &body[body.body_expr];
if let Expr::Block { tail: Some(t), .. } = body_expr {
self.validate_results_in_tail_expr(body.body_expr, *t, db);
} else {
if let Expr::Block { statements, .. } = body_expr {
if let Some(Statement::Expr(id)) = statements.last() {
self.validate_missing_tail_expr(body.body_expr, *id, db);
}
}
}
}
@ -317,6 +325,23 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
}
}
}
fn validate_missing_tail_expr(&mut self, body_id: ExprId, possible_tail_id: ExprId, db: &dyn HirDatabase) {
let mismatch = match self.infer.type_mismatch_for_expr(body_id) {
Some(m) => m,
None => return,
};
if let Some(possible_tail_ty) = self.infer.type_of_expr.get(possible_tail_id) {
if mismatch.actual == Ty::unit() && mismatch.expected == *possible_tail_ty {
let (_, source_map) = db.body_with_source_map(self.owner.into());
if let Ok(source_ptr) = source_map.expr_syntax(possible_tail_id) {
self.sink.push(RemoveThisSemicolon { file: source_ptr.file_id, expr: source_ptr.value });
}
}
}
}
}
pub fn record_literal_missing_fields(