Skip to content

Commit 8450add

Browse files
committed
fix X as ! behavior
1 parent 7eeddb4 commit 8450add

File tree

3 files changed

+31
-5
lines changed

3 files changed

+31
-5
lines changed

src/librustc_typeck/check/cast.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ use util::common::ErrorReported;
5656
pub struct CastCheck<'tcx> {
5757
expr: &'tcx hir::Expr,
5858
expr_ty: Ty<'tcx>,
59+
expr_diverges: Diverges,
5960
cast_ty: Ty<'tcx>,
6061
cast_span: Span,
6162
span: Span,
@@ -115,13 +116,15 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
115116
pub fn new(fcx: &FnCtxt<'a, 'gcx, 'tcx>,
116117
expr: &'tcx hir::Expr,
117118
expr_ty: Ty<'tcx>,
119+
expr_diverges: Diverges,
118120
cast_ty: Ty<'tcx>,
119121
cast_span: Span,
120122
span: Span)
121123
-> Result<CastCheck<'tcx>, ErrorReported> {
122124
let check = CastCheck {
123125
expr: expr,
124126
expr_ty: expr_ty,
127+
expr_diverges: expr_diverges,
125128
cast_ty: cast_ty,
126129
cast_span: cast_span,
127130
span: span,
@@ -378,7 +381,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
378381
// Attempt a coercion to a fn pointer type.
379382
let res = fcx.try_coerce(self.expr,
380383
self.expr_ty,
381-
Diverges::Maybe, // TODO
384+
self.expr_diverges,
382385
fcx.tcx.mk_fn_ptr(f));
383386
if !res.is_ok() {
384387
return Err(CastError::NonScalar);
@@ -545,8 +548,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
545548
}
546549

547550
fn try_coercion_cast(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> bool {
548-
// TODO
549-
fcx.try_coerce(self.expr, self.expr_ty, Diverges::Maybe, self.cast_ty).is_ok()
551+
fcx.try_coerce(self.expr, self.expr_ty, self.expr_diverges, self.cast_ty).is_ok()
550552
}
551553
}
552554

src/librustc_typeck/check/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3736,14 +3736,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
37363736
let t_cast = self.resolve_type_vars_if_possible(&t_cast);
37373737
let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
37383738
let t_cast = self.resolve_type_vars_if_possible(&t_cast);
3739+
let diverges = self.diverges.get();
37393740

37403741
// Eagerly check for some obvious errors.
37413742
if t_expr.references_error() || t_cast.references_error() {
37423743
tcx.types.err
37433744
} else {
37443745
// Defer other checks until we're done type checking.
37453746
let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
3746-
match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
3747+
match cast::CastCheck::new(self, e, t_expr, diverges, t_cast, t.span, expr.span) {
37473748
Ok(cast_check) => {
37483749
deferred_cast_checks.push(cast_check);
37493750
t_cast
@@ -4158,7 +4159,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
41584159
&self.misc(tail_expr.span),
41594160
tail_expr,
41604161
tail_expr_ty,
4161-
self.diverges.get()); // TODO
4162+
self.diverges.get());
41624163
} else {
41634164
// Subtle: if there is no explicit tail expression,
41644165
// that is typically equivalent to a tail expression
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(never_type)]
12+
13+
fn foo(x: usize, y: !, z: usize) { }
14+
15+
fn cast_a() {
16+
let y = {return; 22} as !;
17+
}
18+
19+
fn cast_b() {
20+
let y = 22 as !; //~ ERROR non-scalar cast
21+
}
22+
23+
fn main() { }

0 commit comments

Comments
 (0)