Skip to content

Commit af800c7

Browse files
committed
typeck/expr.rs: move check_expr_assign here.
1 parent 7a41cc1 commit af800c7

File tree

2 files changed

+46
-46
lines changed

2 files changed

+46
-46
lines changed

src/librustc_typeck/check/expr.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
9090
self.check_expr_return(expr_opt.deref(), expr)
9191
}
9292
ExprKind::Assign(ref lhs, ref rhs) => {
93-
self.check_assign(expr, expected, lhs, rhs)
93+
self.check_expr_assign(expr, expected, lhs, rhs)
9494
}
9595
ExprKind::While(ref cond, ref body, _) => {
9696
let ctxt = BreakableCtxt {
@@ -742,4 +742,49 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
742742
}
743743
self.tcx.types.never
744744
}
745+
746+
/// Type check assignment expression `expr` of form `lhs = rhs`.
747+
/// The expected type is `()` and is passsed to the function for the purposes of diagnostics.
748+
fn check_expr_assign(
749+
&self,
750+
expr: &'tcx hir::Expr,
751+
expected: Expectation<'tcx>,
752+
lhs: &'tcx hir::Expr,
753+
rhs: &'tcx hir::Expr,
754+
) -> Ty<'tcx> {
755+
let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
756+
let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
757+
758+
let expected_ty = expected.coercion_target_type(self, expr.span);
759+
if expected_ty == self.tcx.types.bool {
760+
// The expected type is `bool` but this will result in `()` so we can reasonably
761+
// say that the user intended to write `lhs == rhs` instead of `lhs = rhs`.
762+
// The likely cause of this is `if foo = bar { .. }`.
763+
let actual_ty = self.tcx.mk_unit();
764+
let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap();
765+
let msg = "try comparing for equality";
766+
let left = self.tcx.sess.source_map().span_to_snippet(lhs.span);
767+
let right = self.tcx.sess.source_map().span_to_snippet(rhs.span);
768+
if let (Ok(left), Ok(right)) = (left, right) {
769+
let help = format!("{} == {}", left, right);
770+
err.span_suggestion(expr.span, msg, help, Applicability::MaybeIncorrect);
771+
} else {
772+
err.help(msg);
773+
}
774+
err.emit();
775+
} else if !lhs.is_place_expr() {
776+
struct_span_err!(self.tcx.sess, expr.span, E0070,
777+
"invalid left-hand side expression")
778+
.span_label(expr.span, "left-hand of expression not valid")
779+
.emit();
780+
}
781+
782+
self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
783+
784+
if lhs_ty.references_error() || rhs_ty.references_error() {
785+
self.tcx.types.err
786+
} else {
787+
self.tcx.mk_unit()
788+
}
789+
}
745790
}

src/librustc_typeck/check/mod.rs

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3983,51 +3983,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
39833983
ty
39843984
}
39853985

3986-
/// Type check assignment expression `expr` of form `lhs = rhs`.
3987-
/// The expected type is `()` and is passsed to the function for the purposes of diagnostics.
3988-
fn check_assign(
3989-
&self,
3990-
expr: &'tcx hir::Expr,
3991-
expected: Expectation<'tcx>,
3992-
lhs: &'tcx hir::Expr,
3993-
rhs: &'tcx hir::Expr,
3994-
) -> Ty<'tcx> {
3995-
let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
3996-
let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);
3997-
3998-
let expected_ty = expected.coercion_target_type(self, expr.span);
3999-
if expected_ty == self.tcx.types.bool {
4000-
// The expected type is `bool` but this will result in `()` so we can reasonably
4001-
// say that the user intended to write `lhs == rhs` instead of `lhs = rhs`.
4002-
// The likely cause of this is `if foo = bar { .. }`.
4003-
let actual_ty = self.tcx.mk_unit();
4004-
let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap();
4005-
let msg = "try comparing for equality";
4006-
let left = self.tcx.sess.source_map().span_to_snippet(lhs.span);
4007-
let right = self.tcx.sess.source_map().span_to_snippet(rhs.span);
4008-
if let (Ok(left), Ok(right)) = (left, right) {
4009-
let help = format!("{} == {}", left, right);
4010-
err.span_suggestion(expr.span, msg, help, Applicability::MaybeIncorrect);
4011-
} else {
4012-
err.help(msg);
4013-
}
4014-
err.emit();
4015-
} else if !lhs.is_place_expr() {
4016-
struct_span_err!(self.tcx.sess, expr.span, E0070,
4017-
"invalid left-hand side expression")
4018-
.span_label(expr.span, "left-hand of expression not valid")
4019-
.emit();
4020-
}
4021-
4022-
self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
4023-
4024-
if lhs_ty.references_error() || rhs_ty.references_error() {
4025-
self.tcx.types.err
4026-
} else {
4027-
self.tcx.mk_unit()
4028-
}
4029-
}
4030-
40313986
// Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
40323987
// The newly resolved definition is written into `type_dependent_defs`.
40333988
fn finish_resolving_struct_path(&self,

0 commit comments

Comments
 (0)