提交 4c0ff95e 编写于 作者: L leonardo.yvens

Be more explicit about how and why we need fallback in targets of casts

上级 02084f33
......@@ -38,7 +38,7 @@
//! expression, `e as U2` is not necessarily so (in fact it will only be valid if
//! `U1` coerces to `U2`).
use super::{Diverges, FnCtxt};
use super::{Diverges, Fallback, FnCtxt};
use errors::DiagnosticBuilder;
use hir::def_id::DefId;
......@@ -392,7 +392,13 @@ fn trivial_cast_lint(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
}
pub fn check(mut self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
self.expr_ty = fcx.resolved_type(self.span, self.expr_ty);
self.expr_ty = fcx.structurally_resolved_type(self.span, self.expr_ty);
// For backwards compatibility we apply numeric fallback here. This means that in:
// `let x = 100; x as u8;`, we infer `x` to `i32` rather than `u8`.
if self.expr_ty.is_ty_infer() {
fcx.apply_fallback_if_possible(self.expr_ty, Fallback::Numeric);
self.expr_ty = fcx.structurally_resolved_type(self.span, self.expr_ty);
}
self.cast_ty = fcx.structurally_resolved_type(self.span, self.cast_ty);
debug!("check_cast({}, {:?} as {:?})",
......
......@@ -1724,6 +1724,12 @@ enum TupleArgumentsFlag {
TupleArguments,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Fallback {
Full,
Numeric
}
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
......@@ -2133,7 +2139,7 @@ fn resolve_generator_interiors(&self, def_id: DefId) {
// unconstrained floats with f64.
// Defaulting inference variables becomes very dubious if we have
// encountered type-checking errors. In that case, fallback to TyError.
fn apply_fallback_if_possible(&self, ty: Ty<'tcx>) {
fn apply_fallback_if_possible(&self, ty: Ty<'tcx>, fallback: Fallback) {
use rustc::ty::error::UnconstrainedNumeric::Neither;
use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
......@@ -2142,7 +2148,8 @@ fn apply_fallback_if_possible(&self, ty: Ty<'tcx>) {
_ if self.is_tainted_by_errors() => self.tcx().types.err,
UnconstrainedInt => self.tcx.types.i32,
UnconstrainedFloat => self.tcx.types.f64,
Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
Neither if self.type_var_diverges(ty) && fallback == Fallback::Full
=> self.tcx.mk_diverging_default(),
Neither => return
};
debug!("default_type_parameters: defaulting `{:?}` to `{:?}`", ty, fallback);
......@@ -2159,7 +2166,7 @@ fn select_all_obligations_or_error(&self) {
self.select_obligations_where_possible();
for ty in &self.unsolved_variables() {
self.apply_fallback_if_possible(ty);
self.apply_fallback_if_possible(ty, Fallback::Full);
}
let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
......@@ -4937,22 +4944,6 @@ pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
}
}
// Same as `structurally_resolved_type` but also resolves numeric vars, with fallback.
pub fn resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
let mut ty = self.resolve_type_vars_with_obligations(ty);
if !ty.is_ty_infer() {
return ty;
} else {
self.apply_fallback_if_possible(ty);
ty = self.resolve_type_vars_with_obligations(ty);
if !ty.is_ty_infer() {
ty
} else { // Fallback failed, error.
self.must_be_known_in_context(sp, ty)
}
}
}
fn must_be_known_in_context(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
if !self.is_tainted_by_errors() {
type_error_struct!(self.tcx.sess, sp, ty, E0619,
......
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub fn main() {
let cap = 512 * 512;
cap as u8;
// Assert `cap` did not get inferred to `u8` and overflowed.
assert_ne!(cap, 0);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册