Rollup merge of #65213 - estebank:peel-drop-temps, r=Centril
Ignore `ExprKind::DropTemps` for some ref suggestions Introduce `Expr::peel_drop_temps()` to ignore `ExprKind::DropTemps` for suggestions that depend on the `ExprKind` for accuracy.
This commit is contained in:
commit
ff51611c42
6 changed files with 29 additions and 15 deletions
|
@ -1548,6 +1548,19 @@ impl Expr {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// If `Self.kind` is `ExprKind::DropTemps(expr)`, drill down until we get a non-`DropTemps`
|
||||
/// `Expr`. This is used in suggestions to ignore this `ExprKind` as it is semantically
|
||||
/// silent, only signaling the ownership system. By doing this, suggestions that check the
|
||||
/// `ExprKind` of any given `Expr` for presentation don't have to care about `DropTemps`
|
||||
/// beyond remembering to call this function before doing analysis on it.
|
||||
pub fn peel_drop_temps(&self) -> &Self {
|
||||
let mut expr = self;
|
||||
while let ExprKind::DropTemps(inner) = &expr.kind {
|
||||
expr = inner;
|
||||
}
|
||||
expr
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Expr {
|
||||
|
|
|
@ -115,6 +115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
Err(e) => e
|
||||
};
|
||||
|
||||
let expr = expr.peel_drop_temps();
|
||||
let cause = self.misc(expr.span);
|
||||
let expr_ty = self.resolve_type_vars_with_obligations(checked_ty);
|
||||
let mut err = self.report_mismatched_types(&cause, expected, expr_ty, e);
|
||||
|
@ -355,6 +356,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
};
|
||||
let is_macro = sp.from_expansion() && !is_desugaring;
|
||||
|
||||
// `ExprKind::DropTemps` is semantically irrelevant for these suggestions.
|
||||
let expr = expr.peel_drop_temps();
|
||||
|
||||
match (&expr.kind, &expected.kind, &checked_ty.kind) {
|
||||
(_, &ty::Ref(_, exp, _), &ty::Ref(_, check, _)) => match (&exp.kind, &check.kind) {
|
||||
(&ty::Str, &ty::Array(arr, _)) |
|
||||
|
|
|
@ -87,12 +87,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) {
|
||||
let expr = expr.peel_drop_temps();
|
||||
self.suggest_ref_or_into(&mut err, expr, expected_ty, ty);
|
||||
|
||||
let expr = match &expr.kind {
|
||||
ExprKind::DropTemps(expr) => expr,
|
||||
_ => expr,
|
||||
};
|
||||
extend_err(&mut err);
|
||||
// Error possibly reported in `check_assign` so avoid emitting error again.
|
||||
err.emit_unless(self.is_assign_to_bool(expr, expected_ty));
|
||||
|
|
|
@ -4216,20 +4216,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
pub fn suggest_mismatched_types_on_tail(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
expression: &'tcx hir::Expr,
|
||||
expr: &'tcx hir::Expr,
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
cause_span: Span,
|
||||
blk_id: hir::HirId,
|
||||
) -> bool {
|
||||
self.suggest_missing_semicolon(err, expression, expected, cause_span);
|
||||
let expr = expr.peel_drop_temps();
|
||||
self.suggest_missing_semicolon(err, expr, expected, cause_span);
|
||||
let mut pointing_at_return_type = false;
|
||||
if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
|
||||
pointing_at_return_type = self.suggest_missing_return_type(
|
||||
err, &fn_decl, expected, found, can_suggest);
|
||||
}
|
||||
self.suggest_ref_or_into(err, expression, expected, found);
|
||||
self.suggest_boxing_when_appropriate(err, expression, expected, found);
|
||||
self.suggest_ref_or_into(err, expr, expected, found);
|
||||
self.suggest_boxing_when_appropriate(err, expr, expected, found);
|
||||
pointing_at_return_type
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ LL | if &true {}
|
|||
| ^^^^^
|
||||
| |
|
||||
| expected bool, found &bool
|
||||
| help: consider dereferencing the borrow: `*&true`
|
||||
| help: consider removing the borrow: `true`
|
||||
|
|
||||
= note: expected type `bool`
|
||||
found type `&bool`
|
||||
|
@ -41,7 +41,7 @@ LL | if &mut true {}
|
|||
| ^^^^^^^^^
|
||||
| |
|
||||
| expected bool, found &mut bool
|
||||
| help: consider dereferencing the borrow: `*&mut true`
|
||||
| help: consider removing the borrow: `true`
|
||||
|
|
||||
= note: expected type `bool`
|
||||
found type `&mut bool`
|
||||
|
@ -77,7 +77,7 @@ LL | while &true {}
|
|||
| ^^^^^
|
||||
| |
|
||||
| expected bool, found &bool
|
||||
| help: consider dereferencing the borrow: `*&true`
|
||||
| help: consider removing the borrow: `true`
|
||||
|
|
||||
= note: expected type `bool`
|
||||
found type `&bool`
|
||||
|
@ -89,7 +89,7 @@ LL | while &mut true {}
|
|||
| ^^^^^^^^^
|
||||
| |
|
||||
| expected bool, found &mut bool
|
||||
| help: consider dereferencing the borrow: `*&mut true`
|
||||
| help: consider removing the borrow: `true`
|
||||
|
|
||||
= note: expected type `bool`
|
||||
found type `&mut bool`
|
||||
|
|
|
@ -520,7 +520,7 @@ LL | if &let 0 = 0 {}
|
|||
| ^^^^^^^^^^
|
||||
| |
|
||||
| expected bool, found &bool
|
||||
| help: consider dereferencing the borrow: `*&let 0 = 0`
|
||||
| help: consider removing the borrow: `let 0 = 0`
|
||||
|
|
||||
= note: expected type `bool`
|
||||
found type `&bool`
|
||||
|
@ -708,7 +708,7 @@ LL | while &let 0 = 0 {}
|
|||
| ^^^^^^^^^^
|
||||
| |
|
||||
| expected bool, found &bool
|
||||
| help: consider dereferencing the borrow: `*&let 0 = 0`
|
||||
| help: consider removing the borrow: `let 0 = 0`
|
||||
|
|
||||
= note: expected type `bool`
|
||||
found type `&bool`
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue