Skip to content

Commit 55621b6

Browse files
jroeschJared Roesch
authored and
Jared Roesch
committed
Add feature gate
1 parent 9da04b2 commit 55621b6

13 files changed

+74
-10
lines changed

src/doc/reference.md

+2
Original file line numberDiff line numberDiff line change
@@ -2368,6 +2368,8 @@ The currently implemented features of the reference compiler are:
23682368
internally without imposing on callers
23692369
(i.e. making them behave like function calls in
23702370
terms of encapsulation).
2371+
* - `default_type_parameter_fallback` - Allows type parameter defaults to
2372+
influence type inference.
23712373

23722374
If a feature is promoted to a language feature, then all existing programs will
23732375
start to receive compilation warnings about `#![feature]` directives which enabled

src/librustc_typeck/check/mod.rs

+39-1
Original file line numberDiff line numberDiff line change
@@ -1709,10 +1709,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17091709
}
17101710
}
17111711

1712+
/// Apply "fallbacks" to some types
1713+
/// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
1714+
pub fn default_type_parameters(&self) {
1715+
use middle::ty::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat, Neither};
1716+
for ty in &self.infcx().unsolved_variables() {
1717+
let resolved = self.infcx().resolve_type_vars_if_possible(ty);
1718+
if self.infcx().type_var_diverges(resolved) {
1719+
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1720+
} else {
1721+
match self.infcx().type_is_unconstrained_numeric(resolved) {
1722+
UnconstrainedInt => {
1723+
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1724+
},
1725+
UnconstrainedFloat => {
1726+
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1727+
}
1728+
Neither => { }
1729+
}
1730+
}
1731+
}
1732+
}
1733+
17121734
fn select_all_obligations_and_apply_defaults(&self) {
1735+
if self.tcx().sess.features.borrow().default_type_parameter_fallback {
1736+
self.new_select_all_obligations_and_apply_defaults();
1737+
} else {
1738+
self.old_select_all_obligations_and_apply_defaults();
1739+
}
1740+
}
1741+
1742+
// Implements old type inference fallback algorithm
1743+
fn old_select_all_obligations_and_apply_defaults(&self) {
1744+
self.select_obligations_where_possible();
1745+
self.default_type_parameters();
1746+
self.select_obligations_where_possible();
1747+
}
1748+
1749+
fn new_select_all_obligations_and_apply_defaults(&self) {
17131750
use middle::ty::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat, Neither};
17141751

1715-
// For the time being this errs on the side of being memory wasteful but provides better
1752+
// For the time being this errs on the side of being memory wasteful but provides better
17161753
// error reporting.
17171754
// let type_variables = self.infcx().type_variables.clone();
17181755

@@ -1934,6 +1971,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19341971
assert!(self.inh.deferred_call_resolutions.borrow().is_empty());
19351972

19361973
self.select_all_obligations_and_apply_defaults();
1974+
19371975
let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut();
19381976
match fulfillment_cx.select_all_or_error(self.infcx()) {
19391977
Ok(()) => { }

src/libsyntax/feature_gate.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
163163

164164
// Allows the definition recursive static items.
165165
("static_recursion", "1.3.0", Active),
166+
// Allows default type parameters to influence type inference.
167+
("default_type_parameter_fallback", "1.3.0", Active)
166168
];
167169
// (changing above list without updating src/doc/reference.md makes @cmr sad)
168170

@@ -341,7 +343,8 @@ pub struct Features {
341343
/// #![feature] attrs for non-language (library) features
342344
pub declared_lib_features: Vec<(InternedString, Span)>,
343345
pub const_fn: bool,
344-
pub static_recursion: bool
346+
pub static_recursion: bool,
347+
pub default_type_parameter_fallback: bool,
345348
}
346349

347350
impl Features {
@@ -366,7 +369,8 @@ impl Features {
366369
declared_stable_lang_features: Vec::new(),
367370
declared_lib_features: Vec::new(),
368371
const_fn: false,
369-
static_recursion: false
372+
static_recursion: false,
373+
default_type_parameter_fallback: false,
370374
}
371375
}
372376
}
@@ -865,6 +869,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
865869
declared_lib_features: unknown_features,
866870
const_fn: cx.has_feature("const_fn"),
867871
static_recursion: cx.has_feature("static_recursion")
872+
default_type_parameter_fallback: cx.has_feature("default_type_parameter_fallback"),
868873
}
869874
}
870875

src/test/compile-fail/default_ty_param_conflict.rs

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(default_type_parameter_fallback)]
12+
1113
use std::fmt::Debug;
1214

1315
// Example from the RFC

src/test/compile-fail/default_ty_param_conflict_cross_crate.rs

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
// except according to those terms.
1010
//
1111
//aux-build:default_ty_param_cross_crate_crate.rs
12+
13+
#![feature(default_type_parameter_fallback)]
14+
1215
extern crate default_param_test;
1316

1417
use default_param_test::{Foo, bleh};

src/test/run-pass/default_ty_param_default_dependent_associated_type.rs

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010
//
11+
12+
#![feature(default_type_parameter_fallback)]
13+
1114
use std::marker::PhantomData;
1215

1316
trait Id {

src/test/run-pass/default_ty_param_dependent_defaults.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010
//
1111

12+
#![feature(default_type_parameter_fallback)]
1213
use std::marker::PhantomData;
1314

1415
struct Foo<T,U=T> { t: T, data: PhantomData<U> }

src/test/run-pass/default_ty_param_method_call_test.rs

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(default_type_parameter_fallback)]
12+
1113
struct Foo;
1214

1315
impl Foo {

src/test/run-pass/default_ty_param_struct.rs

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(default_type_parameter_fallback)]
12+
1113
struct Foo<A>(A);
1214

1315
impl<A:Default=i32> Foo<A> {

src/test/run-pass/default_ty_param_struct_and_type_alias.rs

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
// except according to those terms.
1010
//
1111

12+
#![feature(default_type_parameter_fallback)]
13+
1214
use std::marker::PhantomData;
1315

1416
struct DeterministicHasher;

src/test/run-pass/default_ty_param_trait_impl.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(default_type_parameter_fallback)]
12+
1113
// Another example from the RFC
1214
trait Foo { }
1315
trait Bar { }
1416

15-
impl<T:Bar=usize> Foo for Vec<T> {} // Impl 1
16-
impl Bar for usize { } // Impl 2
17+
impl<T:Bar=usize> Foo for Vec<T> {}
18+
impl Bar for usize {}
1719

18-
fn takes_foo<F:Foo>(f: F) { }
20+
fn takes_foo<F:Foo>(f: F) {}
1921

2022
fn main() {
2123
let x = Vec::new(); // x: Vec<$0>

src/test/run-pass/default_ty_param_trait_impl_simple.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,17 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(default_type_parameter_fallback)]
12+
1113
// An example from the RFC
1214
trait Foo { fn takes_foo(&self); }
1315
trait Bar { }
1416

1517
impl<T:Bar=usize> Foo for Vec<T> {
1618
fn takes_foo(&self) {}
17-
} // Impl 1
18-
19-
impl Bar for usize { } // Impl 2
19+
}
2020

21-
// fn takes_foo<F:Foo>(f: F) { }
21+
impl Bar for usize {}
2222

2323
fn main() {
2424
let x = Vec::new(); // x: Vec<$0>

src/test/run-pass/default_ty_param_type_alias.rs

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(default_type_parameter_fallback)]
12+
1113
use std::collections::HashMap;
1214

1315
type IntMap<K=usize> = HashMap<K, usize>;

0 commit comments

Comments
 (0)