Skip to content

Commit

Permalink
Add feature gate
Browse files Browse the repository at this point in the history
  • Loading branch information
jroesch authored and Jared Roesch committed Jul 26, 2015
1 parent 9da04b2 commit 55621b6
Show file tree
Hide file tree
Showing 13 changed files with 74 additions and 10 deletions.
2 changes: 2 additions & 0 deletions src/doc/reference.md
Expand Up @@ -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
Expand Down
40 changes: 39 additions & 1 deletion src/librustc_typeck/check/mod.rs
Expand Up @@ -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();

Expand Down Expand Up @@ -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(()) => { }
Expand Down
9 changes: 7 additions & 2 deletions src/libsyntax/feature_gate.rs
Expand Up @@ -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)

Expand Down Expand Up @@ -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 {
Expand All @@ -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,
}
}
}
Expand Down Expand Up @@ -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"),
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/test/compile-fail/default_ty_param_conflict.rs
Expand Up @@ -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
Expand Down
Expand Up @@ -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};
Expand Down
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions src/test/run-pass/default_ty_param_dependent_defaults.rs
Expand Up @@ -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> }
Expand Down
2 changes: 2 additions & 0 deletions src/test/run-pass/default_ty_param_method_call_test.rs
Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions src/test/run-pass/default_ty_param_struct.rs
Expand Up @@ -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> {
Expand Down
2 changes: 2 additions & 0 deletions src/test/run-pass/default_ty_param_struct_and_type_alias.rs
Expand Up @@ -9,6 +9,8 @@
// except according to those terms.
//

#![feature(default_type_parameter_fallback)]

use std::marker::PhantomData;

struct DeterministicHasher;
Expand Down
8 changes: 5 additions & 3 deletions src/test/run-pass/default_ty_param_trait_impl.rs
Expand Up @@ -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>
Expand Down
8 changes: 4 additions & 4 deletions src/test/run-pass/default_ty_param_trait_impl_simple.rs
Expand Up @@ -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>
Expand Down
2 changes: 2 additions & 0 deletions src/test/run-pass/default_ty_param_type_alias.rs
Expand Up @@ -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>;
Expand Down

0 comments on commit 55621b6

Please sign in to comment.