diff options
| author | leonardo.yvens <leoyvens@gmail.com> | 2018-02-08 17:36:17 -0200 |
|---|---|---|
| committer | leonardo.yvens <leoyvens@gmail.com> | 2018-02-08 17:36:17 -0200 |
| commit | d49d428f791b97c476c066deb9c2b3c20165199f (patch) | |
| tree | da9dd8704a3abc58e61f3532bffaa98e5d7a18a8 | |
| parent | b813718f6dff49b851fcd18a5674640554bda2e5 (diff) | |
| download | rust-d49d428f791b97c476c066deb9c2b3c20165199f.tar.gz rust-d49d428f791b97c476c066deb9c2b3c20165199f.zip | |
Revert checking casts before fallback.
This turns out to not be backwards compatible.
| -rw-r--r-- | src/librustc_typeck/check/cast.rs | 11 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 25 | ||||
| -rw-r--r-- | src/test/run-pass/cast-does-fallback.rs | 4 | ||||
| -rw-r--r-- | src/test/ui/issue-45730.rs | 4 | ||||
| -rw-r--r-- | src/test/ui/issue-45730.stderr | 8 |
5 files changed, 17 insertions, 35 deletions
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index dae5ba14bfb..48bd7b14fc9 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -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, Fallback, FnCtxt}; +use super::{Diverges, FnCtxt}; use errors::DiagnosticBuilder; use hir::def_id::DefId; @@ -290,9 +290,6 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { } CastError::UnknownCastPtrKind | CastError::UnknownExprPtrKind => { - if fcx.is_tainted_by_errors() { - return; - } let unknown_cast_to = match e { CastError::UnknownCastPtrKind => true, CastError::UnknownExprPtrKind => false, @@ -396,12 +393,6 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { pub fn check(mut self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) { 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.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 {:?})", diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 0395b3eb4aa..f50bd03a9e0 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -858,17 +858,19 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fcx }; - fcx.check_casts(); - // All type checking constraints were added, try to fallback unsolved variables. fcx.select_obligations_where_possible(); for ty in &fcx.unsolved_variables() { - fcx.fallback_if_possible(ty, Fallback::Full); + fcx.fallback_if_possible(ty); } fcx.select_obligations_where_possible(); + // Even though coercion casts provide type hints, we check casts after fallback for + // backwards compatibility. This makes fallback a stronger type hint than a cast coercion. + fcx.check_casts(); + // Closure and generater analysis may run after fallback - // because they doen't constrain other type variables. + // because they don't constrain other type variables. fcx.closure_analyze(body); assert!(fcx.deferred_call_resolutions.borrow().is_empty()); fcx.resolve_generator_interiors(def_id); @@ -1734,12 +1736,6 @@ 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>, @@ -2149,7 +2145,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // unconstrained floats with f64. // Fallback becomes very dubious if we have encountered type-checking errors. // In that case, fallback to TyError. - fn fallback_if_possible(&self, ty: Ty<'tcx>, fallback: Fallback) { + fn fallback_if_possible(&self, ty: Ty<'tcx>) { use rustc::ty::error::UnconstrainedNumeric::Neither; use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat}; @@ -2158,12 +2154,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, '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) => { - match fallback { - Fallback::Full => self.tcx.mk_diverging_default(), - Fallback::Numeric => return, - } - } + Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(), Neither => return }; debug!("default_type_parameters: defaulting `{:?}` to `{:?}`", ty, fallback); diff --git a/src/test/run-pass/cast-does-fallback.rs b/src/test/run-pass/cast-does-fallback.rs index 86d6e387b25..aa6752ffc35 100644 --- a/src/test/run-pass/cast-does-fallback.rs +++ b/src/test/run-pass/cast-does-fallback.rs @@ -9,6 +9,10 @@ // except according to those terms. pub fn main() { + // Test that these type check correctly. + (&42u8 >> 4) as usize; + (&42u8 << 4) as usize; + let cap = 512 * 512; cap as u8; // Assert `cap` did not get inferred to `u8` and overflowed. diff --git a/src/test/ui/issue-45730.rs b/src/test/ui/issue-45730.rs index 1fe0b1ae2d2..d733c8e6de2 100644 --- a/src/test/ui/issue-45730.rs +++ b/src/test/ui/issue-45730.rs @@ -11,13 +11,9 @@ use std::fmt; fn main() { let x: *const _ = 0 as _; //~ ERROR cannot cast -} -fn a() { let x: *const _ = 0 as *const _; //~ ERROR cannot cast let y: Option<*const fmt::Debug> = Some(x) as _; -} -fn c() { let x = 0 as *const i32 as *const _ as *mut _; //~ ERROR cannot cast } diff --git a/src/test/ui/issue-45730.stderr b/src/test/ui/issue-45730.stderr index 13205eead43..94d39239117 100644 --- a/src/test/ui/issue-45730.stderr +++ b/src/test/ui/issue-45730.stderr @@ -9,9 +9,9 @@ error[E0641]: cannot cast to a pointer of an unknown kind = note: The type information given here is insufficient to check whether the pointer cast is valid error[E0641]: cannot cast to a pointer of an unknown kind - --> $DIR/issue-45730.rs:17:23 + --> $DIR/issue-45730.rs:15:23 | -17 | let x: *const _ = 0 as *const _; //~ ERROR cannot cast +15 | let x: *const _ = 0 as *const _; //~ ERROR cannot cast | ^^^^^-------- | | | help: consider giving more type information @@ -19,9 +19,9 @@ error[E0641]: cannot cast to a pointer of an unknown kind = note: The type information given here is insufficient to check whether the pointer cast is valid error[E0641]: cannot cast to a pointer of an unknown kind - --> $DIR/issue-45730.rs:22:13 + --> $DIR/issue-45730.rs:18:13 | -22 | let x = 0 as *const i32 as *const _ as *mut _; //~ ERROR cannot cast +18 | let x = 0 as *const i32 as *const _ as *mut _; //~ ERROR cannot cast | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------ | | | help: consider giving more type information |
