Skip to content

Commit a551fe0

Browse files
committed
typeck/expr.rs: move check_expr_with_expectation_and_needs here.
1 parent 8fd2d12 commit a551fe0

File tree

2 files changed

+60
-60
lines changed

2 files changed

+60
-60
lines changed

src/librustc_typeck/check/expr.rs

+60-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,66 @@ use rustc::ty::subst::InternalSubsts;
3434
use rustc::traits::{self, ObligationCauseCode};
3535

3636
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
37-
pub(super) fn check_expr_kind(
37+
/// Invariant:
38+
/// If an expression has any sub-expressions that result in a type error,
39+
/// inspecting that expression's type with `ty.references_error()` will return
40+
/// true. Likewise, if an expression is known to diverge, inspecting its
41+
/// type with `ty::type_is_bot` will return true (n.b.: since Rust is
42+
/// strict, _|_ can appear in the type of an expression that does not,
43+
/// itself, diverge: for example, fn() -> _|_.)
44+
/// Note that inspecting a type's structure *directly* may expose the fact
45+
/// that there are actually multiple representations for `Error`, so avoid
46+
/// that when err needs to be handled differently.
47+
pub(super) fn check_expr_with_expectation_and_needs(
48+
&self,
49+
expr: &'tcx hir::Expr,
50+
expected: Expectation<'tcx>,
51+
needs: Needs,
52+
) -> Ty<'tcx> {
53+
debug!(">> type-checking: expr={:?} expected={:?}",
54+
expr, expected);
55+
56+
// Warn for expressions after diverging siblings.
57+
self.warn_if_unreachable(expr.hir_id, expr.span, "expression");
58+
59+
// Hide the outer diverging and has_errors flags.
60+
let old_diverges = self.diverges.get();
61+
let old_has_errors = self.has_errors.get();
62+
self.diverges.set(Diverges::Maybe);
63+
self.has_errors.set(false);
64+
65+
let ty = self.check_expr_kind(expr, expected, needs);
66+
67+
// Warn for non-block expressions with diverging children.
68+
match expr.node {
69+
ExprKind::Block(..) |
70+
ExprKind::Loop(..) | ExprKind::While(..) |
71+
ExprKind::Match(..) => {}
72+
73+
_ => self.warn_if_unreachable(expr.hir_id, expr.span, "expression")
74+
}
75+
76+
// Any expression that produces a value of type `!` must have diverged
77+
if ty.is_never() {
78+
self.diverges.set(self.diverges.get() | Diverges::Always);
79+
}
80+
81+
// Record the type, which applies it effects.
82+
// We need to do this after the warning above, so that
83+
// we don't warn for the diverging expression itself.
84+
self.write_ty(expr.hir_id, ty);
85+
86+
// Combine the diverging and has_error flags.
87+
self.diverges.set(self.diverges.get() | old_diverges);
88+
self.has_errors.set(self.has_errors.get() | old_has_errors);
89+
90+
debug!("type of {} is...", self.tcx.hir().hir_to_string(expr.hir_id));
91+
debug!("... {:?}, expected is {:?}", ty, expected);
92+
93+
ty
94+
}
95+
96+
fn check_expr_kind(
3897
&self,
3998
expr: &'tcx hir::Expr,
4099
expected: Expectation<'tcx>,

src/librustc_typeck/check/mod.rs

-59
Original file line numberDiff line numberDiff line change
@@ -3864,65 +3864,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38643864
}
38653865
}
38663866

3867-
/// Invariant:
3868-
/// If an expression has any sub-expressions that result in a type error,
3869-
/// inspecting that expression's type with `ty.references_error()` will return
3870-
/// true. Likewise, if an expression is known to diverge, inspecting its
3871-
/// type with `ty::type_is_bot` will return true (n.b.: since Rust is
3872-
/// strict, _|_ can appear in the type of an expression that does not,
3873-
/// itself, diverge: for example, fn() -> _|_.)
3874-
/// Note that inspecting a type's structure *directly* may expose the fact
3875-
/// that there are actually multiple representations for `Error`, so avoid
3876-
/// that when err needs to be handled differently.
3877-
fn check_expr_with_expectation_and_needs(
3878-
&self,
3879-
expr: &'tcx hir::Expr,
3880-
expected: Expectation<'tcx>,
3881-
needs: Needs,
3882-
) -> Ty<'tcx> {
3883-
debug!(">> type-checking: expr={:?} expected={:?}",
3884-
expr, expected);
3885-
3886-
// Warn for expressions after diverging siblings.
3887-
self.warn_if_unreachable(expr.hir_id, expr.span, "expression");
3888-
3889-
// Hide the outer diverging and has_errors flags.
3890-
let old_diverges = self.diverges.get();
3891-
let old_has_errors = self.has_errors.get();
3892-
self.diverges.set(Diverges::Maybe);
3893-
self.has_errors.set(false);
3894-
3895-
let ty = self.check_expr_kind(expr, expected, needs);
3896-
3897-
// Warn for non-block expressions with diverging children.
3898-
match expr.node {
3899-
ExprKind::Block(..) |
3900-
ExprKind::Loop(..) | ExprKind::While(..) |
3901-
ExprKind::Match(..) => {}
3902-
3903-
_ => self.warn_if_unreachable(expr.hir_id, expr.span, "expression")
3904-
}
3905-
3906-
// Any expression that produces a value of type `!` must have diverged
3907-
if ty.is_never() {
3908-
self.diverges.set(self.diverges.get() | Diverges::Always);
3909-
}
3910-
3911-
// Record the type, which applies it effects.
3912-
// We need to do this after the warning above, so that
3913-
// we don't warn for the diverging expression itself.
3914-
self.write_ty(expr.hir_id, ty);
3915-
3916-
// Combine the diverging and has_error flags.
3917-
self.diverges.set(self.diverges.get() | old_diverges);
3918-
self.has_errors.set(self.has_errors.get() | old_has_errors);
3919-
3920-
debug!("type of {} is...", self.tcx.hir().hir_to_string(expr.hir_id));
3921-
debug!("... {:?}, expected is {:?}", ty, expected);
3922-
3923-
ty
3924-
}
3925-
39263867
// Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
39273868
// The newly resolved definition is written into `type_dependent_defs`.
39283869
fn finish_resolving_struct_path(&self,

0 commit comments

Comments
 (0)