Skip to content

Commit

Permalink
Review comments
Browse files Browse the repository at this point in the history
- exhaustive match
- rename method to `check_expr_meets_expectation_or_error`
- formatting
- add `delay_span_bug`
- add test
  • Loading branch information
estebank committed Jun 16, 2017
1 parent 028b5f9 commit da78b4d
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 21 deletions.
4 changes: 2 additions & 2 deletions src/librustc_typeck/check/_match.rs
Expand Up @@ -413,7 +413,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// discriminant. This is sort of a workaround, see note (*) in
// `check_pat` for some details.
discrim_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(discrim.span));
self.check_expr_has_type(discrim, discrim_ty);
self.check_expr_has_type_or_error(discrim, discrim_ty);
};

// If the discriminant diverges, the match is pointless (e.g.,
Expand Down Expand Up @@ -480,7 +480,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
for (i, (arm, pats_diverge)) in arms.iter().zip(all_arm_pats_diverge).enumerate() {
if let Some(ref e) = arm.guard {
self.diverges.set(pats_diverge);
self.check_expr_has_type(e, tcx.types.bool);
self.check_expr_has_type_or_error(e, tcx.types.bool);
}

self.diverges.set(pats_diverge);
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_typeck/check/demand.rs
Expand Up @@ -29,7 +29,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.demand_suptype_diag(sp, expected, actual).map(|mut e| e.emit());
}

pub fn demand_suptype_diag(&self, sp: Span,
pub fn demand_suptype_diag(&self,
sp: Span,
expected: Ty<'tcx>,
actual: Ty<'tcx>) -> Option<DiagnosticBuilder<'tcx>> {
let cause = &self.misc(sp);
Expand Down
31 changes: 17 additions & 14 deletions src/librustc_typeck/check/mod.rs
Expand Up @@ -345,7 +345,7 @@ impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
match self.resolve(fcx) {
ExpectHasType(ty) => Some(ty),
ExpectIfCondition => Some(fcx.tcx.types.bool),
_ => None
NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
}
}

Expand Down Expand Up @@ -2647,15 +2647,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.demand_eqtype(expr.span, expected, ty);
}

pub fn check_expr_has_type(&self,
expr: &'gcx hir::Expr,
expected: Ty<'tcx>) -> Ty<'tcx> {
self.check_expr_expect_type(expr, ExpectHasType(expected))
pub fn check_expr_has_type_or_error(&self,
expr: &'gcx hir::Expr,
expected: Ty<'tcx>) -> Ty<'tcx> {
self.check_expr_meets_expectation_or_error(expr, ExpectHasType(expected))
}

fn check_expr_expect_type(&self,
expr: &'gcx hir::Expr,
expected: Expectation<'tcx>) -> Ty<'tcx> {
fn check_expr_meets_expectation_or_error(&self,
expr: &'gcx hir::Expr,
expected: Expectation<'tcx>) -> Ty<'tcx> {
let expected_ty = expected.to_option(&self).unwrap_or(self.tcx.types.bool);
let mut ty = self.check_expr_with_expectation(expr, expected);

Expand Down Expand Up @@ -2865,7 +2865,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
opt_else_expr: Option<&'gcx hir::Expr>,
sp: Span,
expected: Expectation<'tcx>) -> Ty<'tcx> {
let cond_ty = self.check_expr_expect_type(cond_expr, ExpectIfCondition);
let cond_ty = self.check_expr_meets_expectation_or_error(cond_expr, ExpectIfCondition);
let cond_diverges = self.diverges.get();
self.diverges.set(Diverges::Maybe);

Expand Down Expand Up @@ -3352,7 +3352,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.check_expr_struct_fields(struct_ty, expected, expr.id, path_span, variant, fields,
base_expr.is_none());
if let &Some(ref base_expr) = base_expr {
self.check_expr_has_type(base_expr, struct_ty);
self.check_expr_has_type_or_error(base_expr, struct_ty);
match struct_ty.sty {
ty::TyAdt(adt, substs) if adt.is_struct() => {
let fru_field_types = adt.struct_variant().fields.iter().map(|f| {
Expand Down Expand Up @@ -3668,7 +3668,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty);

match expected {
ExpectIfCondition => (),
ExpectIfCondition => {
self.tcx.sess.delay_span_bug(lhs.span, "invalid lhs expression in if;\
expected error elsehwere");
}
_ => {
// Only check this if not in an `if` condition, as the
// mistyped comparison help is more appropriate.
Expand Down Expand Up @@ -3704,7 +3707,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
};

self.with_breakable_ctxt(expr.id, ctxt, || {
self.check_expr_has_type(&cond, tcx.types.bool);
self.check_expr_has_type_or_error(&cond, tcx.types.bool);
let cond_diverging = self.diverges.get();
self.check_block_no_value(&body);

Expand Down Expand Up @@ -3842,7 +3845,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
None => {
let t: Ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span));
let element_ty = self.check_expr_has_type(&element, t);
let element_ty = self.check_expr_has_type_or_error(&element, t);
(element_ty, t)
}
};
Expand Down Expand Up @@ -4097,7 +4100,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
hir::StmtExpr(ref expr, _) => {
// Check with expected type of ()
self.check_expr_has_type(&expr, self.tcx.mk_nil());
self.check_expr_has_type_or_error(&expr, self.tcx.mk_nil());
}
hir::StmtSemi(ref expr, _) => {
self.check_expr(&expr);
Expand Down
Expand Up @@ -45,4 +45,8 @@ fn main() {
//~| HELP did you mean to compare equality?
println!("{}", x);
}
if (if true { x = 4 } else { x = 5 }) {
//~^ ERROR mismatched types
println!("{}", x);
}
}
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
--> $DIR/issue-17283.rs:25:8
--> $DIR/assignment-in-if.rs:25:8
|
25 | if x = x {
| ^^^^^
Expand All @@ -11,7 +11,7 @@ error[E0308]: mismatched types
found type `()`

error[E0308]: mismatched types
--> $DIR/issue-17283.rs:31:8
--> $DIR/assignment-in-if.rs:31:8
|
31 | if (x = x) {
| ^^^^^^^
Expand All @@ -23,7 +23,7 @@ error[E0308]: mismatched types
found type `()`

error[E0308]: mismatched types
--> $DIR/issue-17283.rs:37:8
--> $DIR/assignment-in-if.rs:37:8
|
37 | if y = (Foo { foo: x }) {
| ^^^^^^^^^^^^^^^^^^^^
Expand All @@ -35,7 +35,7 @@ error[E0308]: mismatched types
found type `()`

error[E0308]: mismatched types
--> $DIR/issue-17283.rs:43:8
--> $DIR/assignment-in-if.rs:43:8
|
43 | if 3 = x {
| ^^^^^
Expand All @@ -46,5 +46,14 @@ error[E0308]: mismatched types
= note: expected type `bool`
found type `()`

error[E0308]: mismatched types
--> $DIR/assignment-in-if.rs:48:8
|
48 | if (if true { x = 4 } else { x = 5 }) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found ()
|
= note: expected type `bool`
found type `()`

error: aborting due to previous error(s)

0 comments on commit da78b4d

Please sign in to comment.