Auto merge of #14326 - iDawer:refactor, r=Veykril
internal: Rename `hir::diagnostics::MissingMatchArms.match_expr` field `hir::diagnostics::MissingMatchArms.match_expr` had confusing name: it is pointing to scrutinee expression. Renamed to `scrutinee_expr` and used better fitting type for it. Also small refactorings/cleanup.
This commit is contained in:
commit
70e10deee8
4 changed files with 21 additions and 23 deletions
|
@ -84,7 +84,7 @@ impl ExprValidator {
|
||||||
|
|
||||||
match expr {
|
match expr {
|
||||||
Expr::Match { expr, arms } => {
|
Expr::Match { expr, arms } => {
|
||||||
self.validate_match(id, *expr, arms, db, self.infer.clone());
|
self.validate_match(id, *expr, arms, db);
|
||||||
}
|
}
|
||||||
Expr::Call { .. } | Expr::MethodCall { .. } => {
|
Expr::Call { .. } | Expr::MethodCall { .. } => {
|
||||||
self.validate_call(db, id, expr, &mut filter_map_next_checker);
|
self.validate_call(db, id, expr, &mut filter_map_next_checker);
|
||||||
|
@ -147,16 +147,15 @@ impl ExprValidator {
|
||||||
|
|
||||||
fn validate_match(
|
fn validate_match(
|
||||||
&mut self,
|
&mut self,
|
||||||
id: ExprId,
|
|
||||||
match_expr: ExprId,
|
match_expr: ExprId,
|
||||||
|
scrutinee_expr: ExprId,
|
||||||
arms: &[MatchArm],
|
arms: &[MatchArm],
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
infer: Arc<InferenceResult>,
|
|
||||||
) {
|
) {
|
||||||
let body = db.body(self.owner);
|
let body = db.body(self.owner);
|
||||||
|
|
||||||
let match_expr_ty = &infer[match_expr];
|
let scrut_ty = &self.infer[scrutinee_expr];
|
||||||
if match_expr_ty.is_unknown() {
|
if scrut_ty.is_unknown() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,23 +165,23 @@ impl ExprValidator {
|
||||||
let mut m_arms = Vec::with_capacity(arms.len());
|
let mut m_arms = Vec::with_capacity(arms.len());
|
||||||
let mut has_lowering_errors = false;
|
let mut has_lowering_errors = false;
|
||||||
for arm in arms {
|
for arm in arms {
|
||||||
if let Some(pat_ty) = infer.type_of_pat.get(arm.pat) {
|
if let Some(pat_ty) = self.infer.type_of_pat.get(arm.pat) {
|
||||||
// We only include patterns whose type matches the type
|
// We only include patterns whose type matches the type
|
||||||
// of the match expression. If we had an InvalidMatchArmPattern
|
// of the scrutinee expression. If we had an InvalidMatchArmPattern
|
||||||
// diagnostic or similar we could raise that in an else
|
// diagnostic or similar we could raise that in an else
|
||||||
// block here.
|
// block here.
|
||||||
//
|
//
|
||||||
// When comparing the types, we also have to consider that rustc
|
// When comparing the types, we also have to consider that rustc
|
||||||
// will automatically de-reference the match expression type if
|
// will automatically de-reference the scrutinee expression type if
|
||||||
// necessary.
|
// necessary.
|
||||||
//
|
//
|
||||||
// FIXME we should use the type checker for this.
|
// FIXME we should use the type checker for this.
|
||||||
if (pat_ty == match_expr_ty
|
if (pat_ty == scrut_ty
|
||||||
|| match_expr_ty
|
|| scrut_ty
|
||||||
.as_reference()
|
.as_reference()
|
||||||
.map(|(match_expr_ty, ..)| match_expr_ty == pat_ty)
|
.map(|(match_expr_ty, ..)| match_expr_ty == pat_ty)
|
||||||
.unwrap_or(false))
|
.unwrap_or(false))
|
||||||
&& types_of_subpatterns_do_match(arm.pat, &body, &infer)
|
&& types_of_subpatterns_do_match(arm.pat, &body, &self.infer)
|
||||||
{
|
{
|
||||||
// If we had a NotUsefulMatchArm diagnostic, we could
|
// If we had a NotUsefulMatchArm diagnostic, we could
|
||||||
// check the usefulness of each pattern as we added it
|
// check the usefulness of each pattern as we added it
|
||||||
|
@ -206,7 +205,7 @@ impl ExprValidator {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let report = compute_match_usefulness(&cx, &m_arms, match_expr_ty);
|
let report = compute_match_usefulness(&cx, &m_arms, scrut_ty);
|
||||||
|
|
||||||
// FIXME Report unreacheble arms
|
// FIXME Report unreacheble arms
|
||||||
// https://github.com/rust-lang/rust/blob/f31622a50/compiler/rustc_mir_build/src/thir/pattern/check_match.rs#L200
|
// https://github.com/rust-lang/rust/blob/f31622a50/compiler/rustc_mir_build/src/thir/pattern/check_match.rs#L200
|
||||||
|
@ -214,8 +213,8 @@ impl ExprValidator {
|
||||||
let witnesses = report.non_exhaustiveness_witnesses;
|
let witnesses = report.non_exhaustiveness_witnesses;
|
||||||
if !witnesses.is_empty() {
|
if !witnesses.is_empty() {
|
||||||
self.diagnostics.push(BodyValidationDiagnostic::MissingMatchArms {
|
self.diagnostics.push(BodyValidationDiagnostic::MissingMatchArms {
|
||||||
match_expr: id,
|
match_expr,
|
||||||
uncovered_patterns: missing_match_arms(&cx, match_expr_ty, witnesses, arms),
|
uncovered_patterns: missing_match_arms(&cx, scrut_ty, witnesses, arms),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -379,7 +378,7 @@ fn missing_match_arms<'p>(
|
||||||
arms: &[MatchArm],
|
arms: &[MatchArm],
|
||||||
) -> String {
|
) -> String {
|
||||||
struct DisplayWitness<'a, 'p>(&'a DeconstructedPat<'p>, &'a MatchCheckCtx<'a, 'p>);
|
struct DisplayWitness<'a, 'p>(&'a DeconstructedPat<'p>, &'a MatchCheckCtx<'a, 'p>);
|
||||||
impl<'a, 'p> fmt::Display for DisplayWitness<'a, 'p> {
|
impl fmt::Display for DisplayWitness<'_, '_> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let DisplayWitness(witness, cx) = *self;
|
let DisplayWitness(witness, cx) = *self;
|
||||||
let pat = witness.to_pat(cx);
|
let pat = witness.to_pat(cx);
|
||||||
|
|
|
@ -199,8 +199,7 @@ pub struct MismatchedArgCount {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MissingMatchArms {
|
pub struct MissingMatchArms {
|
||||||
pub file: HirFileId,
|
pub scrutinee_expr: InFile<AstPtr<ast::Expr>>,
|
||||||
pub match_expr: AstPtr<ast::Expr>,
|
|
||||||
pub uncovered_patterns: String,
|
pub uncovered_patterns: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1628,11 +1628,13 @@ impl DefWithBody {
|
||||||
if let ast::Expr::MatchExpr(match_expr) =
|
if let ast::Expr::MatchExpr(match_expr) =
|
||||||
&source_ptr.value.to_node(&root)
|
&source_ptr.value.to_node(&root)
|
||||||
{
|
{
|
||||||
if let Some(match_expr) = match_expr.expr() {
|
if let Some(scrut_expr) = match_expr.expr() {
|
||||||
acc.push(
|
acc.push(
|
||||||
MissingMatchArms {
|
MissingMatchArms {
|
||||||
file: source_ptr.file_id,
|
scrutinee_expr: InFile::new(
|
||||||
match_expr: AstPtr::new(&match_expr),
|
source_ptr.file_id,
|
||||||
|
AstPtr::new(&scrut_expr),
|
||||||
|
),
|
||||||
uncovered_patterns,
|
uncovered_patterns,
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use hir::InFile;
|
|
||||||
|
|
||||||
use crate::{Diagnostic, DiagnosticsContext};
|
use crate::{Diagnostic, DiagnosticsContext};
|
||||||
|
|
||||||
// Diagnostic: missing-match-arm
|
// Diagnostic: missing-match-arm
|
||||||
|
@ -12,7 +10,7 @@ pub(crate) fn missing_match_arms(
|
||||||
Diagnostic::new(
|
Diagnostic::new(
|
||||||
"missing-match-arm",
|
"missing-match-arm",
|
||||||
format!("missing match arm: {}", d.uncovered_patterns),
|
format!("missing match arm: {}", d.uncovered_patterns),
|
||||||
ctx.sema.diagnostics_display_range(InFile::new(d.file, d.match_expr.clone().into())).range,
|
ctx.sema.diagnostics_display_range(d.scrutinee_expr.clone().map(Into::into)).range,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue