about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJared Roesch <roeschinc@gmail.com>2015-07-24 13:39:11 -0700
committerJared Roesch <jroesch@MacBook.home>2015-07-25 20:05:42 -0700
commit55621b6199dcef7090bdbb660a5ab9354b3effa6 (patch)
treef1a353116a88e0e35e64f9b8548b2f09e2f6e582
parent9da04b2bd1fdcd147f6d0ebcdbb5108f63bf7576 (diff)
downloadrust-55621b6199dcef7090bdbb660a5ab9354b3effa6.tar.gz
rust-55621b6199dcef7090bdbb660a5ab9354b3effa6.zip
Add feature gate
-rw-r--r--src/doc/reference.md2
-rw-r--r--src/librustc_typeck/check/mod.rs40
-rw-r--r--src/libsyntax/feature_gate.rs9
-rw-r--r--src/test/compile-fail/default_ty_param_conflict.rs2
-rw-r--r--src/test/compile-fail/default_ty_param_conflict_cross_crate.rs3
-rw-r--r--src/test/run-pass/default_ty_param_default_dependent_associated_type.rs3
-rw-r--r--src/test/run-pass/default_ty_param_dependent_defaults.rs1
-rw-r--r--src/test/run-pass/default_ty_param_method_call_test.rs2
-rw-r--r--src/test/run-pass/default_ty_param_struct.rs2
-rw-r--r--src/test/run-pass/default_ty_param_struct_and_type_alias.rs2
-rw-r--r--src/test/run-pass/default_ty_param_trait_impl.rs8
-rw-r--r--src/test/run-pass/default_ty_param_trait_impl_simple.rs8
-rw-r--r--src/test/run-pass/default_ty_param_type_alias.rs2
13 files changed, 74 insertions, 10 deletions
diff --git a/src/doc/reference.md b/src/doc/reference.md
index 26fd2fd8d20..59721edda70 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -2368,6 +2368,8 @@ The currently implemented features of the reference compiler are:
                               internally without imposing on callers
                               (i.e. making them behave like function calls in
                               terms of encapsulation).
+* - `default_type_parameter_fallback` - Allows type parameter defaults to
+                                        influence type inference.
 
 If a feature is promoted to a language feature, then all existing programs will
 start to receive compilation warnings about `#![feature]` directives which enabled
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 95e916f1a0d..eb0ef30d396 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1709,10 +1709,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
+    /// 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 ty in &self.infcx().unsolved_variables() {
+            let resolved = self.infcx().resolve_type_vars_if_possible(ty);
+            if self.infcx().type_var_diverges(resolved) {
+                demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
+            } 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 => { }
+                }
+            }
+        }
+    }
+
     fn select_all_obligations_and_apply_defaults(&self) {
+        if self.tcx().sess.features.borrow().default_type_parameter_fallback {
+            self.new_select_all_obligations_and_apply_defaults();
+        } else {
+            self.old_select_all_obligations_and_apply_defaults();
+        }
+    }
+
+    // Implements old type inference fallback algorithm
+    fn old_select_all_obligations_and_apply_defaults(&self) {
+        self.select_obligations_where_possible();
+        self.default_type_parameters();
+        self.select_obligations_where_possible();
+    }
+
+    fn new_select_all_obligations_and_apply_defaults(&self) {
         use middle::ty::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat, Neither};
 
-        // For the time being this errs on the side of being memory wasteful but provides better
+            // For the time being this errs on the side of being memory wasteful but provides better
         // error reporting.
         // let type_variables = self.infcx().type_variables.clone();
 
@@ -1934,6 +1971,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
 
         self.select_all_obligations_and_apply_defaults();
+
         let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
         match fulfillment_cx.select_all_or_error(self.infcx()) {
             Ok(()) => { }
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index ee895fb1a96..af7e4a6855f 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -163,6 +163,8 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
 
     // Allows the definition recursive static items.
     ("static_recursion", "1.3.0", Active),
+// Allows default type parameters to influence type inference.
+    ("default_type_parameter_fallback", "1.3.0", Active)
 ];
 // (changing above list without updating src/doc/reference.md makes @cmr sad)
 
@@ -341,7 +343,8 @@ pub struct Features {
     /// #![feature] attrs for non-language (library) features
     pub declared_lib_features: Vec<(InternedString, Span)>,
     pub const_fn: bool,
-    pub static_recursion: bool
+    pub static_recursion: bool,
+    pub default_type_parameter_fallback: bool,
 }
 
 impl Features {
@@ -366,7 +369,8 @@ impl Features {
             declared_stable_lang_features: Vec::new(),
             declared_lib_features: Vec::new(),
             const_fn: false,
-            static_recursion: false
+            static_recursion: false,
+            default_type_parameter_fallback: false,
         }
     }
 }
@@ -865,6 +869,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
         declared_lib_features: unknown_features,
         const_fn: cx.has_feature("const_fn"),
         static_recursion: cx.has_feature("static_recursion")
+        default_type_parameter_fallback: cx.has_feature("default_type_parameter_fallback"),
     }
 }
 
diff --git a/src/test/compile-fail/default_ty_param_conflict.rs b/src/test/compile-fail/default_ty_param_conflict.rs
index 42de545f9d0..48c5cd1ff77 100644
--- a/src/test/compile-fail/default_ty_param_conflict.rs
+++ b/src/test/compile-fail/default_ty_param_conflict.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(default_type_parameter_fallback)]
+
 use std::fmt::Debug;
 
 // Example from the RFC
diff --git a/src/test/compile-fail/default_ty_param_conflict_cross_crate.rs b/src/test/compile-fail/default_ty_param_conflict_cross_crate.rs
index 804a864e074..4d60724372a 100644
--- a/src/test/compile-fail/default_ty_param_conflict_cross_crate.rs
+++ b/src/test/compile-fail/default_ty_param_conflict_cross_crate.rs
@@ -9,6 +9,9 @@
 // except according to those terms.
 //
 //aux-build:default_ty_param_cross_crate_crate.rs
+
+#![feature(default_type_parameter_fallback)]
+
 extern crate default_param_test;
 
 use default_param_test::{Foo, bleh};
diff --git a/src/test/run-pass/default_ty_param_default_dependent_associated_type.rs b/src/test/run-pass/default_ty_param_default_dependent_associated_type.rs
index fe8c1063c96..8fc2c2e6bce 100644
--- a/src/test/run-pass/default_ty_param_default_dependent_associated_type.rs
+++ b/src/test/run-pass/default_ty_param_default_dependent_associated_type.rs
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
+
+#![feature(default_type_parameter_fallback)]
+
 use std::marker::PhantomData;
 
 trait Id {
diff --git a/src/test/run-pass/default_ty_param_dependent_defaults.rs b/src/test/run-pass/default_ty_param_dependent_defaults.rs
index eba86415af4..ac833d0f547 100644
--- a/src/test/run-pass/default_ty_param_dependent_defaults.rs
+++ b/src/test/run-pass/default_ty_param_dependent_defaults.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 //
 
+#![feature(default_type_parameter_fallback)]
 use std::marker::PhantomData;
 
 struct Foo<T,U=T> { t: T, data: PhantomData<U> }
diff --git a/src/test/run-pass/default_ty_param_method_call_test.rs b/src/test/run-pass/default_ty_param_method_call_test.rs
index 35f0fcab001..e8d93092ec5 100644
--- a/src/test/run-pass/default_ty_param_method_call_test.rs
+++ b/src/test/run-pass/default_ty_param_method_call_test.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(default_type_parameter_fallback)]
+
 struct Foo;
 
 impl Foo {
diff --git a/src/test/run-pass/default_ty_param_struct.rs b/src/test/run-pass/default_ty_param_struct.rs
index b94b759fd11..d9ac51fc23b 100644
--- a/src/test/run-pass/default_ty_param_struct.rs
+++ b/src/test/run-pass/default_ty_param_struct.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(default_type_parameter_fallback)]
+
 struct Foo<A>(A);
 
 impl<A:Default=i32> Foo<A> {
diff --git a/src/test/run-pass/default_ty_param_struct_and_type_alias.rs b/src/test/run-pass/default_ty_param_struct_and_type_alias.rs
index 0a8543c03b1..6e3e60a02e5 100644
--- a/src/test/run-pass/default_ty_param_struct_and_type_alias.rs
+++ b/src/test/run-pass/default_ty_param_struct_and_type_alias.rs
@@ -9,6 +9,8 @@
 // except according to those terms.
 //
 
+#![feature(default_type_parameter_fallback)]
+
 use std::marker::PhantomData;
 
 struct DeterministicHasher;
diff --git a/src/test/run-pass/default_ty_param_trait_impl.rs b/src/test/run-pass/default_ty_param_trait_impl.rs
index fbceb60b9a8..c67d3a49aff 100644
--- a/src/test/run-pass/default_ty_param_trait_impl.rs
+++ b/src/test/run-pass/default_ty_param_trait_impl.rs
@@ -8,14 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(default_type_parameter_fallback)]
+
 // Another example from the RFC
 trait Foo { }
 trait Bar { }
 
-impl<T:Bar=usize> Foo for Vec<T> {} // Impl 1
-impl Bar for usize { } // Impl 2
+impl<T:Bar=usize> Foo for Vec<T> {}
+impl Bar for usize {}
 
-fn takes_foo<F:Foo>(f: F) { }
+fn takes_foo<F:Foo>(f: F) {}
 
 fn main() {
     let x = Vec::new(); // x: Vec<$0>
diff --git a/src/test/run-pass/default_ty_param_trait_impl_simple.rs b/src/test/run-pass/default_ty_param_trait_impl_simple.rs
index 00d7ccf43be..067ad524922 100644
--- a/src/test/run-pass/default_ty_param_trait_impl_simple.rs
+++ b/src/test/run-pass/default_ty_param_trait_impl_simple.rs
@@ -8,17 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(default_type_parameter_fallback)]
+
 // An example from the RFC
 trait Foo { fn takes_foo(&self); }
 trait Bar { }
 
 impl<T:Bar=usize> Foo for Vec<T> {
     fn takes_foo(&self) {}
-} // Impl 1
-
-impl Bar for usize { } // Impl 2
+}
 
-// fn takes_foo<F:Foo>(f: F) { }
+impl Bar for usize {}
 
 fn main() {
     let x = Vec::new(); // x: Vec<$0>
diff --git a/src/test/run-pass/default_ty_param_type_alias.rs b/src/test/run-pass/default_ty_param_type_alias.rs
index c3e44e55bee..1b4747406d0 100644
--- a/src/test/run-pass/default_ty_param_type_alias.rs
+++ b/src/test/run-pass/default_ty_param_type_alias.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(default_type_parameter_fallback)]
+
 use std::collections::HashMap;
 
 type IntMap<K=usize> = HashMap<K, usize>;