Add feature gate
This commit is contained in:
parent
9da04b2bd1
commit
55621b6199
@ -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
|
||||
|
@ -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(()) => { }
|
||||
|
@ -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"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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};
|
||||
|
@ -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 {
|
||||
|
@ -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> }
|
||||
|
@ -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 {
|
||||
|
@ -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> {
|
||||
|
@ -9,6 +9,8 @@
|
||||
// except according to those terms.
|
||||
//
|
||||
|
||||
#![feature(default_type_parameter_fallback)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
struct DeterministicHasher;
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>;
|
||||
|
Loading…
x
Reference in New Issue
Block a user