diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 6d031c8650756..4e1fffa6ae593 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -23,7 +23,7 @@ pub use self::freshen::TypeFreshener; use middle::subst; use middle::subst::Substs; -use middle::ty::{TyVid, IntVid, FloatVid, RegionVid}; +use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric}; use middle::ty::replace_late_bound_regions; use middle::ty::{mod, Ty}; use middle::ty_fold::{TypeFolder, TypeFoldable}; @@ -519,6 +519,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { freshen::TypeFreshener::new(self) } + pub fn type_is_unconstrained_numeric(&'a self, ty: Ty) -> UnconstrainedNumeric { + use middle::ty::UnconstrainedNumeric::{Neither, UnconstrainedInt, UnconstrainedFloat}; + match ty.sty { + ty::ty_infer(ty::IntVar(vid)) => { + match self.int_unification_table.borrow_mut().get(self.tcx, vid).value { + None => UnconstrainedInt, + _ => Neither, + } + }, + ty::ty_infer(ty::FloatVar(vid)) => { + match self.float_unification_table.borrow_mut().get(self.tcx, vid).value { + None => return UnconstrainedFloat, + _ => Neither, + } + }, + _ => Neither, + } + } + pub fn combine_fields<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>) -> CombineFields<'b, 'tcx> { CombineFields {infcx: self, diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index b2cc52ab0a87b..819b39f1eb679 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1495,6 +1495,14 @@ pub enum InferTy { FreshIntTy(uint), } +#[deriving(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Show, Copy)] +pub enum UnconstrainedNumeric { + UnconstrainedFloat, + UnconstrainedInt, + Neither, +} + + #[deriving(Clone, RustcEncodable, RustcDecodable, Eq, Hash, Show, Copy)] pub enum InferRegion { ReVar(RegionVid), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index fbd40ef6fed0e..9a4dce00f1c30 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -413,7 +413,6 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, vtable::select_all_fcx_obligations_or_error(&fcx); regionck::regionck_fn(&fcx, id, decl, body); - fcx.default_diverging_type_variables_to_nil(); writeback::resolve_type_vars_in_fn(&fcx, decl, body); } _ => ccx.tcx.sess.impossible_case(body.span, @@ -1573,10 +1572,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn default_diverging_type_variables_to_nil(&self) { + /// Apply "fallbacks" to some types + /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64. + pub fn default_type_parameters(&self) { + use middle::ty::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat, Neither}; for (_, &ref ty) in self.inh.node_types.borrow_mut().iter_mut() { - if self.infcx().type_var_diverges(self.infcx().resolve_type_vars_if_possible(ty)) { + let resolved = self.infcx().resolve_type_vars_if_possible(ty); + if self.infcx().type_var_diverges(resolved) { demand::eqtype(self, codemap::DUMMY_SP, *ty, ty::mk_nil(self.tcx())); + } else { + match self.infcx().type_is_unconstrained_numeric(resolved) { + UnconstrainedInt => { + demand::eqtype(self, codemap::DUMMY_SP, *ty, ty::mk_i32()) + }, + UnconstrainedFloat => { + demand::eqtype(self, codemap::DUMMY_SP, *ty, ty::mk_f64()) + } + Neither => { } + } } } } diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs index e23bf46b564b3..4096908ec312e 100644 --- a/src/librustc_typeck/check/vtable.rs +++ b/src/librustc_typeck/check/vtable.rs @@ -279,6 +279,9 @@ pub fn register_object_cast_obligations<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, pub fn select_all_fcx_obligations_or_error(fcx: &FnCtxt) { debug!("select_all_fcx_obligations_or_error"); + select_fcx_obligations_where_possible(fcx); + fcx.default_type_parameters(); + let mut fulfillment_cx = fcx.inh.fulfillment_cx.borrow_mut(); let r = fulfillment_cx.select_all_or_error(fcx.infcx(), &fcx.inh.param_env, diff --git a/src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs b/src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs index 9ceae41d1a465..6ce043ae94b82 100644 --- a/src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs +++ b/src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs @@ -33,7 +33,7 @@ where T : Convert } fn a() { - test(22_i32, 44); //~ ERROR unable to infer + test(22_i32, std::default::Default::default()); //~ ERROR unable to infer } fn main() {} diff --git a/src/test/compile-fail/issue-6458-1.rs b/src/test/run-fail/issue-6458-1.rs similarity index 92% rename from src/test/compile-fail/issue-6458-1.rs rename to src/test/run-fail/issue-6458-1.rs index 52a57fa2f4411..631517f6a3ca6 100644 --- a/src/test/compile-fail/issue-6458-1.rs +++ b/src/test/run-fail/issue-6458-1.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// error-pattern:explicit panic + fn foo(t: T) {} fn main() { foo(panic!()) } - //~^ ERROR type annotations required diff --git a/src/test/compile-fail/integer-literal-suffix-inference-2.rs b/src/test/run-pass/integer-literal-suffix-inference-2.rs similarity index 88% rename from src/test/compile-fail/integer-literal-suffix-inference-2.rs rename to src/test/run-pass/integer-literal-suffix-inference-2.rs index 7c862d04d206d..05973a545a20d 100644 --- a/src/test/compile-fail/integer-literal-suffix-inference-2.rs +++ b/src/test/run-pass/integer-literal-suffix-inference-2.rs @@ -11,7 +11,7 @@ fn foo(_: *const ()) {} fn main() { - let a = 3; //~ ERROR cannot determine a type for this local variable + let a = 3; foo(&a as *const _ as *const ()); } diff --git a/src/test/compile-fail/integer-literal-suffix-inference-3.rs b/src/test/run-pass/integer-literal-suffix-inference-3.rs similarity index 89% rename from src/test/compile-fail/integer-literal-suffix-inference-3.rs rename to src/test/run-pass/integer-literal-suffix-inference-3.rs index dc3db98566030..05b275a0d8cab 100644 --- a/src/test/compile-fail/integer-literal-suffix-inference-3.rs +++ b/src/test/run-pass/integer-literal-suffix-inference-3.rs @@ -10,6 +10,5 @@ fn main() { println!("{}", std::mem::size_of_val(&1)); - //~^ ERROR cannot determine a type for this expression } diff --git a/src/test/compile-fail/issue-11382.rs b/src/test/run-pass/issue-11382.rs similarity index 80% rename from src/test/compile-fail/issue-11382.rs rename to src/test/run-pass/issue-11382.rs index 44f6cd7719d1d..51996614d259f 100644 --- a/src/test/compile-fail/issue-11382.rs +++ b/src/test/run-pass/issue-11382.rs @@ -9,8 +9,5 @@ // except according to those terms. fn main() { -panic!( - 1.2 -//~^ ERROR cannot determine the type of this number; add a suffix to specify the type explicitly -); + println!("{}", 1.2); } diff --git a/src/test/compile-fail/issue-15730.rs b/src/test/run-pass/issue-15730.rs similarity index 85% rename from src/test/compile-fail/issue-15730.rs rename to src/test/run-pass/issue-15730.rs index c29e74af03cd2..a1a5922e15003 100644 --- a/src/test/compile-fail/issue-15730.rs +++ b/src/test/run-pass/issue-15730.rs @@ -12,6 +12,5 @@ fn main() { let mut array = [1, 2, 3]; -//~^ ERROR cannot determine a type for this local variable: cannot determine the type of this integ let pie_slice = array[1..2]; } diff --git a/src/test/compile-fail/issue-16783.rs b/src/test/run-pass/issue-16783.rs similarity index 84% rename from src/test/compile-fail/issue-16783.rs rename to src/test/run-pass/issue-16783.rs index 1b52bd9c3de9d..cb12d138a5f29 100644 --- a/src/test/compile-fail/issue-16783.rs +++ b/src/test/run-pass/issue-16783.rs @@ -10,6 +10,5 @@ pub fn main() { let x = [1, 2, 3]; - //~^ ERROR cannot determine a type for this local variable: cannot determine the type of this let y = x.as_slice(); } diff --git a/src/test/run-pass/traits-multidispatch-infer-convert-source-and-target.rs b/src/test/run-pass/traits-multidispatch-infer-convert-source-and-target.rs index c10029791df52..87a5253fd8c6d 100644 --- a/src/test/run-pass/traits-multidispatch-infer-convert-source-and-target.rs +++ b/src/test/run-pass/traits-multidispatch-infer-convert-source-and-target.rs @@ -30,6 +30,7 @@ where T : Convert } fn main() { + use std::default::Default; // T = i16, U = u32 - test(22, 44, 2, 4); + test(Default::default(), Default::default(), 2, 4); } diff --git a/src/test/run-pass/traits-multidispatch-infer-convert-target.rs b/src/test/run-pass/traits-multidispatch-infer-convert-target.rs index 54515f3b0d7d8..ccf0ce72b4cbb 100644 --- a/src/test/run-pass/traits-multidispatch-infer-convert-target.rs +++ b/src/test/run-pass/traits-multidispatch-infer-convert-target.rs @@ -36,11 +36,12 @@ where T : Convert } fn main() { + use std::default::Default; // T = i16, U = u32 - test(22_i16, 44, 2, 4); - test(22, 44_u32, 2, 4); + test(22_i16, Default::default(), 2, 4); + test(Default::default(), 44_u32, 2, 4); // T = u32, U = i16 - test(22_u32, 44, 4, 2); - test(22, 44_i16, 4, 2); + test(22_u32, Default::default(), 4, 2); + test(Default::default(), 44_i16, 4, 2); }