diff options
| author | Jared Roesch <roeschinc@gmail.com> | 2015-07-24 13:39:11 -0700 |
|---|---|---|
| committer | Jared Roesch <jroesch@MacBook.home> | 2015-07-25 20:05:42 -0700 |
| commit | 55621b6199dcef7090bdbb660a5ab9354b3effa6 (patch) | |
| tree | f1a353116a88e0e35e64f9b8548b2f09e2f6e582 | |
| parent | 9da04b2bd1fdcd147f6d0ebcdbb5108f63bf7576 (diff) | |
| download | rust-55621b6199dcef7090bdbb660a5ab9354b3effa6.tar.gz rust-55621b6199dcef7090bdbb660a5ab9354b3effa6.zip | |
Add feature gate
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>; |
