diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 91fbaca26d113..d9b7e04bc7941 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}; @@ -525,6 +525,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 8e7470f5084b0..82a8bc3cd06c1 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1641,6 +1641,14 @@ pub enum InferTy { FreshIntTy(u32), } +#[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 2e3552047b48b..1b45cc2f0d28c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -453,7 +453,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, @@ -1666,10 +1665,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, self.tcx().types.i32) + }, + UnconstrainedFloat => { + demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64) + } + Neither => { } + } } } } diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs index 15e942006f018..c85b542b6caee 100644 --- a/src/librustc_typeck/check/vtable.rs +++ b/src/librustc_typeck/check/vtable.rs @@ -407,6 +407,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/issue-16966.rs b/src/test/compile-fail/issue-16966.rs index dfa23c48afa6e..5dbf7546de224 100644 --- a/src/test/compile-fail/issue-16966.rs +++ b/src/test/compile-fail/issue-16966.rs @@ -8,8 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// error-pattern:type annotations required fn main() { panic!( - 1.2 //~ ERROR cannot determine a type for this expression + std::default::Default::default() ); } 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 3c461fd5b4b70..0a5aa1b7bd346 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 type annotations required + test(22_i32, std::default::Default::default()); //~ ERROR type annotations required } 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 deleted file mode 100644 index c10029791df52..0000000000000 --- a/src/test/run-pass/traits-multidispatch-infer-convert-source-and-target.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that if there is one impl we can infer everything. - -use std::mem; - -trait Convert { - fn convert(&self) -> Target; -} - -impl Convert for i16 { - fn convert(&self) -> u32 { - *self as u32 - } -} - -fn test(_: T, _: U, t_size: uint, u_size: uint) -where T : Convert -{ - assert_eq!(mem::size_of::(), t_size); - assert_eq!(mem::size_of::(), u_size); -} - -fn main() { - // T = i16, U = u32 - test(22, 44, 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..532ef7cbec6f3 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,10 @@ 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); // T = u32, U = i16 - test(22_u32, 44, 4, 2); - test(22, 44_i16, 4, 2); + test(22_u32, Default::default(), 4, 2); }