@@ -34,6 +34,90 @@ use rustc::ty::subst::InternalSubsts;
3434use rustc:: traits:: { self , ObligationCauseCode } ;
3535
3636impl < ' a , ' tcx > FnCtxt < ' a , ' tcx > {
37+ fn check_expr_eq_type ( & self , expr : & ' tcx hir:: Expr , expected : Ty < ' tcx > ) {
38+ let ty = self . check_expr_with_hint ( expr, expected) ;
39+ self . demand_eqtype ( expr. span , expected, ty) ;
40+ }
41+
42+ pub fn check_expr_has_type_or_error (
43+ & self ,
44+ expr : & ' tcx hir:: Expr ,
45+ expected : Ty < ' tcx > ,
46+ ) -> Ty < ' tcx > {
47+ self . check_expr_meets_expectation_or_error ( expr, ExpectHasType ( expected) )
48+ }
49+
50+ fn check_expr_meets_expectation_or_error (
51+ & self ,
52+ expr : & ' tcx hir:: Expr ,
53+ expected : Expectation < ' tcx > ,
54+ ) -> Ty < ' tcx > {
55+ let expected_ty = expected. to_option ( & self ) . unwrap_or ( self . tcx . types . bool ) ;
56+ let mut ty = self . check_expr_with_expectation ( expr, expected) ;
57+
58+ // While we don't allow *arbitrary* coercions here, we *do* allow
59+ // coercions from ! to `expected`.
60+ if ty. is_never ( ) {
61+ assert ! ( !self . tables. borrow( ) . adjustments( ) . contains_key( expr. hir_id) ,
62+ "expression with never type wound up being adjusted" ) ;
63+ let adj_ty = self . next_diverging_ty_var (
64+ TypeVariableOrigin {
65+ kind : TypeVariableOriginKind :: AdjustmentType ,
66+ span : expr. span ,
67+ } ,
68+ ) ;
69+ self . apply_adjustments ( expr, vec ! [ Adjustment {
70+ kind: Adjust :: NeverToAny ,
71+ target: adj_ty
72+ } ] ) ;
73+ ty = adj_ty;
74+ }
75+
76+ if let Some ( mut err) = self . demand_suptype_diag ( expr. span , expected_ty, ty) {
77+ let expr = match & expr. node {
78+ ExprKind :: DropTemps ( expr) => expr,
79+ _ => expr,
80+ } ;
81+ // Error possibly reported in `check_assign` so avoid emitting error again.
82+ err. emit_unless ( self . is_assign_to_bool ( expr, expected_ty) ) ;
83+ }
84+ ty
85+ }
86+
87+ pub ( super ) fn check_expr_coercable_to_type (
88+ & self ,
89+ expr : & ' tcx hir:: Expr ,
90+ expected : Ty < ' tcx >
91+ ) -> Ty < ' tcx > {
92+ let ty = self . check_expr_with_hint ( expr, expected) ;
93+ // checks don't need two phase
94+ self . demand_coerce ( expr, ty, expected, AllowTwoPhase :: No )
95+ }
96+
97+ pub ( super ) fn check_expr_with_hint (
98+ & self ,
99+ expr : & ' tcx hir:: Expr ,
100+ expected : Ty < ' tcx >
101+ ) -> Ty < ' tcx > {
102+ self . check_expr_with_expectation ( expr, ExpectHasType ( expected) )
103+ }
104+
105+ pub ( super ) fn check_expr_with_expectation (
106+ & self ,
107+ expr : & ' tcx hir:: Expr ,
108+ expected : Expectation < ' tcx > ,
109+ ) -> Ty < ' tcx > {
110+ self . check_expr_with_expectation_and_needs ( expr, expected, Needs :: None )
111+ }
112+
113+ pub ( super ) fn check_expr ( & self , expr : & ' tcx hir:: Expr ) -> Ty < ' tcx > {
114+ self . check_expr_with_expectation ( expr, NoExpectation )
115+ }
116+
117+ pub ( super ) fn check_expr_with_needs ( & self , expr : & ' tcx hir:: Expr , needs : Needs ) -> Ty < ' tcx > {
118+ self . check_expr_with_expectation_and_needs ( expr, NoExpectation , needs)
119+ }
120+
37121 /// Invariant:
38122 /// If an expression has any sub-expressions that result in a type error,
39123 /// inspecting that expression's type with `ty.references_error()` will return
@@ -44,7 +128,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
44128 /// Note that inspecting a type's structure *directly* may expose the fact
45129 /// that there are actually multiple representations for `Error`, so avoid
46130 /// that when err needs to be handled differently.
47- pub ( super ) fn check_expr_with_expectation_and_needs (
131+ fn check_expr_with_expectation_and_needs (
48132 & self ,
49133 expr : & ' tcx hir:: Expr ,
50134 expected : Expectation < ' tcx > ,
0 commit comments