Skip to content

Commit d49d428

Browse files
committed
Revert checking casts before fallback.
This turns out to not be backwards compatible.
1 parent b813718 commit d49d428

File tree

5 files changed

+17
-35
lines changed

5 files changed

+17
-35
lines changed

src/librustc_typeck/check/cast.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
//! expression, `e as U2` is not necessarily so (in fact it will only be valid if
3939
//! `U1` coerces to `U2`).
4040
41-
use super::{Diverges, Fallback, FnCtxt};
41+
use super::{Diverges, FnCtxt};
4242

4343
use errors::DiagnosticBuilder;
4444
use hir::def_id::DefId;
@@ -290,9 +290,6 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
290290
}
291291
CastError::UnknownCastPtrKind |
292292
CastError::UnknownExprPtrKind => {
293-
if fcx.is_tainted_by_errors() {
294-
return;
295-
}
296293
let unknown_cast_to = match e {
297294
CastError::UnknownCastPtrKind => true,
298295
CastError::UnknownExprPtrKind => false,
@@ -396,12 +393,6 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
396393

397394
pub fn check(mut self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
398395
self.expr_ty = fcx.structurally_resolved_type(self.span, self.expr_ty);
399-
// For backwards compatibility we apply numeric fallback here. This means that in:
400-
// `let x = 100; x as u8;`, we infer `x` to `i32` rather than `u8`.
401-
if self.expr_ty.is_ty_infer() {
402-
fcx.fallback_if_possible(self.expr_ty, Fallback::Numeric);
403-
self.expr_ty = fcx.structurally_resolved_type(self.span, self.expr_ty);
404-
}
405396
self.cast_ty = fcx.structurally_resolved_type(self.span, self.cast_ty);
406397

407398
debug!("check_cast({}, {:?} as {:?})",

src/librustc_typeck/check/mod.rs

+8-17
Original file line numberDiff line numberDiff line change
@@ -858,17 +858,19 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
858858
fcx
859859
};
860860

861-
fcx.check_casts();
862-
863861
// All type checking constraints were added, try to fallback unsolved variables.
864862
fcx.select_obligations_where_possible();
865863
for ty in &fcx.unsolved_variables() {
866-
fcx.fallback_if_possible(ty, Fallback::Full);
864+
fcx.fallback_if_possible(ty);
867865
}
868866
fcx.select_obligations_where_possible();
869867

868+
// Even though coercion casts provide type hints, we check casts after fallback for
869+
// backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
870+
fcx.check_casts();
871+
870872
// Closure and generater analysis may run after fallback
871-
// because they doen't constrain other type variables.
873+
// because they don't constrain other type variables.
872874
fcx.closure_analyze(body);
873875
assert!(fcx.deferred_call_resolutions.borrow().is_empty());
874876
fcx.resolve_generator_interiors(def_id);
@@ -1734,12 +1736,6 @@ enum TupleArgumentsFlag {
17341736
TupleArguments,
17351737
}
17361738

1737-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1738-
pub enum Fallback {
1739-
Full,
1740-
Numeric
1741-
}
1742-
17431739
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
17441740
pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>,
17451741
param_env: ty::ParamEnv<'tcx>,
@@ -2149,7 +2145,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
21492145
// unconstrained floats with f64.
21502146
// Fallback becomes very dubious if we have encountered type-checking errors.
21512147
// In that case, fallback to TyError.
2152-
fn fallback_if_possible(&self, ty: Ty<'tcx>, fallback: Fallback) {
2148+
fn fallback_if_possible(&self, ty: Ty<'tcx>) {
21532149
use rustc::ty::error::UnconstrainedNumeric::Neither;
21542150
use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
21552151

@@ -2158,12 +2154,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
21582154
_ if self.is_tainted_by_errors() => self.tcx().types.err,
21592155
UnconstrainedInt => self.tcx.types.i32,
21602156
UnconstrainedFloat => self.tcx.types.f64,
2161-
Neither if self.type_var_diverges(ty) => {
2162-
match fallback {
2163-
Fallback::Full => self.tcx.mk_diverging_default(),
2164-
Fallback::Numeric => return,
2165-
}
2166-
}
2157+
Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
21672158
Neither => return
21682159
};
21692160
debug!("default_type_parameters: defaulting `{:?}` to `{:?}`", ty, fallback);

src/test/run-pass/cast-does-fallback.rs

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
// except according to those terms.
1010

1111
pub fn main() {
12+
// Test that these type check correctly.
13+
(&42u8 >> 4) as usize;
14+
(&42u8 << 4) as usize;
15+
1216
let cap = 512 * 512;
1317
cap as u8;
1418
// Assert `cap` did not get inferred to `u8` and overflowed.

src/test/ui/issue-45730.rs

-4
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,9 @@
1111
use std::fmt;
1212
fn main() {
1313
let x: *const _ = 0 as _; //~ ERROR cannot cast
14-
}
1514

16-
fn a() {
1715
let x: *const _ = 0 as *const _; //~ ERROR cannot cast
1816
let y: Option<*const fmt::Debug> = Some(x) as _;
19-
}
2017

21-
fn c() {
2218
let x = 0 as *const i32 as *const _ as *mut _; //~ ERROR cannot cast
2319
}

src/test/ui/issue-45730.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@ error[E0641]: cannot cast to a pointer of an unknown kind
99
= note: The type information given here is insufficient to check whether the pointer cast is valid
1010

1111
error[E0641]: cannot cast to a pointer of an unknown kind
12-
--> $DIR/issue-45730.rs:17:23
12+
--> $DIR/issue-45730.rs:15:23
1313
|
14-
17 | let x: *const _ = 0 as *const _; //~ ERROR cannot cast
14+
15 | let x: *const _ = 0 as *const _; //~ ERROR cannot cast
1515
| ^^^^^--------
1616
| |
1717
| help: consider giving more type information
1818
|
1919
= note: The type information given here is insufficient to check whether the pointer cast is valid
2020

2121
error[E0641]: cannot cast to a pointer of an unknown kind
22-
--> $DIR/issue-45730.rs:22:13
22+
--> $DIR/issue-45730.rs:18:13
2323
|
24-
22 | let x = 0 as *const i32 as *const _ as *mut _; //~ ERROR cannot cast
24+
18 | let x = 0 as *const i32 as *const _ as *mut _; //~ ERROR cannot cast
2525
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------
2626
| |
2727
| help: consider giving more type information

0 commit comments

Comments
 (0)