Skip to content

Commit ccaeb33

Browse files
committed
auto merge of #20189 : cmr/rust/i32-fallback, r=nikomatsakis
Doesn't yet converge on a fixed point, but generally works. A better algorithm will come with the implementation of default type parameter fallback. If inference fails to determine an exact integral or floating point type, it will set the type to i32 or f64, respectively. Closes #16968
2 parents c43efee + ac369ef commit ccaeb33

13 files changed

+59
-19
lines changed

src/librustc/middle/infer/mod.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub use self::freshen::TypeFreshener;
2323

2424
use middle::subst;
2525
use middle::subst::Substs;
26-
use middle::ty::{TyVid, IntVid, FloatVid, RegionVid};
26+
use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric};
2727
use middle::ty::replace_late_bound_regions;
2828
use middle::ty::{mod, Ty};
2929
use middle::ty_fold::{TypeFolder, TypeFoldable};
@@ -522,6 +522,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
522522
freshen::TypeFreshener::new(self)
523523
}
524524

525+
pub fn type_is_unconstrained_numeric(&'a self, ty: Ty) -> UnconstrainedNumeric {
526+
use middle::ty::UnconstrainedNumeric::{Neither, UnconstrainedInt, UnconstrainedFloat};
527+
match ty.sty {
528+
ty::ty_infer(ty::IntVar(vid)) => {
529+
match self.int_unification_table.borrow_mut().get(self.tcx, vid).value {
530+
None => UnconstrainedInt,
531+
_ => Neither,
532+
}
533+
},
534+
ty::ty_infer(ty::FloatVar(vid)) => {
535+
match self.float_unification_table.borrow_mut().get(self.tcx, vid).value {
536+
None => return UnconstrainedFloat,
537+
_ => Neither,
538+
}
539+
},
540+
_ => Neither,
541+
}
542+
}
543+
525544
pub fn combine_fields<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
526545
-> CombineFields<'b, 'tcx> {
527546
CombineFields {infcx: self,

src/librustc/middle/ty.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,14 @@ pub enum InferTy {
14951495
FreshIntTy(uint),
14961496
}
14971497

1498+
#[deriving(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Show, Copy)]
1499+
pub enum UnconstrainedNumeric {
1500+
UnconstrainedFloat,
1501+
UnconstrainedInt,
1502+
Neither,
1503+
}
1504+
1505+
14981506
#[deriving(Clone, RustcEncodable, RustcDecodable, Eq, Hash, Show, Copy)]
14991507
pub enum InferRegion {
15001508
ReVar(RegionVid),

src/librustc_typeck/check/mod.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,6 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
413413

414414
vtable::select_all_fcx_obligations_or_error(&fcx);
415415
regionck::regionck_fn(&fcx, id, decl, body);
416-
fcx.default_diverging_type_variables_to_nil();
417416
writeback::resolve_type_vars_in_fn(&fcx, decl, body);
418417
}
419418
_ => ccx.tcx.sess.impossible_case(body.span,
@@ -1573,10 +1572,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15731572
}
15741573
}
15751574

1576-
pub fn default_diverging_type_variables_to_nil(&self) {
1575+
/// Apply "fallbacks" to some types
1576+
/// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1577+
pub fn default_type_parameters(&self) {
1578+
use middle::ty::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat, Neither};
15771579
for (_, &ref ty) in self.inh.node_types.borrow_mut().iter_mut() {
1578-
if self.infcx().type_var_diverges(self.infcx().resolve_type_vars_if_possible(ty)) {
1580+
let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1581+
if self.infcx().type_var_diverges(resolved) {
15791582
demand::eqtype(self, codemap::DUMMY_SP, *ty, ty::mk_nil(self.tcx()));
1583+
} else {
1584+
match self.infcx().type_is_unconstrained_numeric(resolved) {
1585+
UnconstrainedInt => {
1586+
demand::eqtype(self, codemap::DUMMY_SP, *ty, ty::mk_i32())
1587+
},
1588+
UnconstrainedFloat => {
1589+
demand::eqtype(self, codemap::DUMMY_SP, *ty, ty::mk_f64())
1590+
}
1591+
Neither => { }
1592+
}
15801593
}
15811594
}
15821595
}

src/librustc_typeck/check/vtable.rs

+3
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,9 @@ pub fn register_object_cast_obligations<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
279279
pub fn select_all_fcx_obligations_or_error(fcx: &FnCtxt) {
280280
debug!("select_all_fcx_obligations_or_error");
281281

282+
select_fcx_obligations_where_possible(fcx);
283+
fcx.default_type_parameters();
284+
282285
let mut fulfillment_cx = fcx.inh.fulfillment_cx.borrow_mut();
283286
let r = fulfillment_cx.select_all_or_error(fcx.infcx(),
284287
&fcx.inh.param_env,

src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ where T : Convert<U>
3333
}
3434

3535
fn a() {
36-
test(22_i32, 44); //~ ERROR unable to infer
36+
test(22_i32, std::default::Default::default()); //~ ERROR unable to infer
3737
}
3838

3939
fn main() {}

src/test/compile-fail/issue-6458-1.rs renamed to src/test/run-fail/issue-6458-1.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// error-pattern:explicit panic
12+
1113
fn foo<T>(t: T) {}
1214
fn main() { foo(panic!()) }
13-
//~^ ERROR type annotations required

src/test/compile-fail/integer-literal-suffix-inference-2.rs renamed to src/test/run-pass/integer-literal-suffix-inference-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
fn foo(_: *const ()) {}
1212

1313
fn main() {
14-
let a = 3; //~ ERROR cannot determine a type for this local variable
14+
let a = 3;
1515
foo(&a as *const _ as *const ());
1616
}
1717

src/test/compile-fail/integer-literal-suffix-inference-3.rs renamed to src/test/run-pass/integer-literal-suffix-inference-3.rs

-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,5 @@
1010

1111
fn main() {
1212
println!("{}", std::mem::size_of_val(&1));
13-
//~^ ERROR cannot determine a type for this expression
1413
}
1514

src/test/compile-fail/issue-11382.rs renamed to src/test/run-pass/issue-11382.rs

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

1111
fn main() {
12-
panic!(
13-
1.2
14-
//~^ ERROR cannot determine the type of this number; add a suffix to specify the type explicitly
15-
);
12+
println!("{}", 1.2);
1613
}

src/test/compile-fail/issue-15730.rs renamed to src/test/run-pass/issue-15730.rs

-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,5 @@
1212

1313
fn main() {
1414
let mut array = [1, 2, 3];
15-
//~^ ERROR cannot determine a type for this local variable: cannot determine the type of this integ
1615
let pie_slice = array[1..2];
1716
}

src/test/compile-fail/issue-16783.rs renamed to src/test/run-pass/issue-16783.rs

-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,5 @@
1010

1111
pub fn main() {
1212
let x = [1, 2, 3];
13-
//~^ ERROR cannot determine a type for this local variable: cannot determine the type of this
1413
let y = x.as_slice();
1514
}

src/test/run-pass/traits-multidispatch-infer-convert-source-and-target.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ where T : Convert<U>
3030
}
3131

3232
fn main() {
33+
use std::default::Default;
3334
// T = i16, U = u32
34-
test(22, 44, 2, 4);
35+
test(Default::default(), Default::default(), 2, 4);
3536
}

src/test/run-pass/traits-multidispatch-infer-convert-target.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,12 @@ where T : Convert<U>
3636
}
3737

3838
fn main() {
39+
use std::default::Default;
3940
// T = i16, U = u32
40-
test(22_i16, 44, 2, 4);
41-
test(22, 44_u32, 2, 4);
41+
test(22_i16, Default::default(), 2, 4);
42+
test(Default::default(), 44_u32, 2, 4);
4243

4344
// T = u32, U = i16
44-
test(22_u32, 44, 4, 2);
45-
test(22, 44_i16, 4, 2);
45+
test(22_u32, Default::default(), 4, 2);
46+
test(Default::default(), 44_i16, 4, 2);
4647
}

0 commit comments

Comments
 (0)