Skip to content

Commit 5f02029

Browse files
jroeschJared Roesch
authored andcommitted
---
yaml --- r: 224249 b: refs/heads/beta c: 49eb2c6 h: refs/heads/master i: 224247: 33fe925 v: v3
1 parent 0059d0d commit 5f02029

File tree

7 files changed

+144
-42
lines changed

7 files changed

+144
-42
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ refs/tags/0.9: 36870b185fc5f5486636d4515f0e22677493f225
2323
refs/tags/0.10: ac33f2b15782272ae348dbd7b14b8257b2148b5a
2424
refs/tags/0.11.0: e1247cb1d0d681be034adb4b558b5a0c0d5720f9
2525
refs/tags/0.12.0: f0c419429ef30723ceaf6b42f9b5a2aeb5d2e2d1
26-
refs/heads/beta: bbdca2c8aded0497c289536ee5ead694ca2d8fc0
26+
refs/heads/beta: 49eb2c6763e68ee462b5808ab558b4fa9f84fcc0
2727
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
2828
refs/heads/tmp: 938f5d7af401e2d8238522fed4a612943b6e77fd
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f

branches/beta/src/librustc/middle/infer/mod.rs

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,6 @@ pub struct InferCtxt<'a, 'tcx: 'a> {
9595
normalize: bool,
9696

9797
err_count_on_creation: usize,
98-
99-
// Default Type Parameter fallbacks
100-
pub defaults: RefCell<FnvHashMap<Ty<'tcx>, Ty<'tcx>>>,
10198
}
10299

103100
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
@@ -353,8 +350,7 @@ pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
353350
parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment()),
354351
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(errors_will_be_reported)),
355352
normalize: false,
356-
err_count_on_creation: tcx.sess.err_count(),
357-
defaults: RefCell::new(FnvHashMap()),
353+
err_count_on_creation: tcx.sess.err_count()
358354
}
359355
}
360356

@@ -657,27 +653,44 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
657653
}
658654
}
659655

656+
/// Returns a type variable's default fallback if any exists. A default
657+
/// must be attached to the variable when created, if it is created
658+
/// without a default, this will return None.
659+
///
660+
/// See `new_ty_var_with_default` to create a type variable with a default.
661+
/// See `type_variable::Default` for details about what a default entails.
662+
pub fn default(&self, ty: Ty<'tcx>) -> Option<type_variable::Default<'tcx>> {
663+
match ty.sty {
664+
ty::TyInfer(ty::TyVar(vid)) => self.type_variables.borrow().default(vid),
665+
_ => None
666+
}
667+
}
668+
660669
pub fn unsolved_variables(&self) -> Vec<ty::Ty<'tcx>> {
661670
let mut variables = Vec::new();
662671

663672
let unbound_ty_vars = self.type_variables
664673
.borrow()
665674
.unsolved_variables()
666-
.into_iter().map(|t| self.tcx.mk_var(t));
675+
.into_iter()
676+
.map(|t| self.tcx.mk_var(t));
667677

668678
let unbound_int_vars = self.int_unification_table
669679
.borrow_mut()
670680
.unsolved_variables()
671-
.into_iter().map(|v| self.tcx.mk_int_var(v));
681+
.into_iter()
682+
.map(|v| self.tcx.mk_int_var(v));
672683

673684
let unbound_float_vars = self.float_unification_table
674685
.borrow_mut()
675686
.unsolved_variables()
676-
.into_iter().map(|v| self.tcx.mk_float_var(v));
687+
.into_iter()
688+
.map(|v| self.tcx.mk_float_var(v));
677689

678690
variables.extend(unbound_ty_vars);
679691
variables.extend(unbound_int_vars);
680692
variables.extend(unbound_float_vars);
693+
681694
return variables;
682695
}
683696

@@ -984,13 +997,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
984997
pub fn next_ty_var_id(&self, diverging: bool) -> TyVid {
985998
self.type_variables
986999
.borrow_mut()
987-
.new_var(diverging)
1000+
.new_var(diverging, None)
9881001
}
9891002

9901003
pub fn next_ty_var(&self) -> Ty<'tcx> {
9911004
self.tcx.mk_var(self.next_ty_var_id(false))
9921005
}
9931006

1007+
pub fn next_ty_var_with_default(&self,
1008+
default: Option<type_variable::Default<'tcx>>) -> Ty<'tcx> {
1009+
let ty_var_id = self.type_variables
1010+
.borrow_mut()
1011+
.new_var(false, default);
1012+
1013+
self.tcx.mk_var(ty_var_id)
1014+
}
1015+
9941016
pub fn next_diverging_ty_var(&self) -> Ty<'tcx> {
9951017
self.tcx.mk_var(self.next_ty_var_id(true))
9961018
}
@@ -1027,14 +1049,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10271049
pub fn type_vars_for_defs(&self,
10281050
defs: &[ty::TypeParameterDef<'tcx>])
10291051
-> Vec<ty::Ty<'tcx>> {
1052+
let mut substs = Substs::empty();
10301053
let mut vars = Vec::with_capacity(defs.len());
10311054

10321055
for def in defs.iter() {
1033-
let ty_var = self.next_ty_var();
1034-
match def.default {
1035-
None => {},
1036-
Some(default) => { self.defaults.borrow_mut().insert(ty_var, default); }
1037-
}
1056+
let default = def.default.map(|default| {
1057+
type_variable::Default {
1058+
ty: default
1059+
}
1060+
});
1061+
//.subst(self.tcx, &substs)
1062+
let ty_var = self.next_ty_var_with_default(default);
1063+
substs.types.push(subst::ParamSpace::SelfSpace, ty_var);
10381064
vars.push(ty_var)
10391065
}
10401066

branches/beta/src/librustc/middle/infer/type_variable.rs

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,17 @@ struct TypeVariableData<'tcx> {
3030

3131
enum TypeVariableValue<'tcx> {
3232
Known(Ty<'tcx>),
33-
Bounded(Vec<Relation>),
33+
Bounded {
34+
relations: Vec<Relation>,
35+
default: Option<Default<'tcx>>
36+
}
37+
}
38+
39+
// We will use this to store the required information to recapitulate what happened when
40+
// an error occurs.
41+
#[derive(Clone)]
42+
pub struct Default<'tcx> {
43+
pub ty: Ty<'tcx>
3444
}
3545

3646
pub struct Snapshot {
@@ -72,6 +82,13 @@ impl<'tcx> TypeVariableTable<'tcx> {
7282
relations(self.values.get_mut(a.index as usize))
7383
}
7484

85+
pub fn default(&self, vid: ty::TyVid) -> Option<Default<'tcx>> {
86+
match &self.values.get(vid.index as usize).value {
87+
&Known(_) => None,
88+
&Bounded { ref default, .. } => default.clone()
89+
}
90+
}
91+
7592
pub fn var_diverges<'a>(&'a self, vid: ty::TyVid) -> bool {
7693
self.values.get(vid.index as usize).diverging
7794
}
@@ -102,7 +119,7 @@ impl<'tcx> TypeVariableTable<'tcx> {
102119
};
103120

104121
let relations = match old_value {
105-
Bounded(b) => b,
122+
Bounded { relations, .. } => relations,
106123
Known(_) => panic!("Asked to instantiate variable that is \
107124
already instantiated")
108125
};
@@ -114,17 +131,19 @@ impl<'tcx> TypeVariableTable<'tcx> {
114131
self.values.record(SpecifyVar(vid, relations));
115132
}
116133

117-
pub fn new_var(&mut self, diverging: bool) -> ty::TyVid {
134+
pub fn new_var(&mut self,
135+
diverging: bool,
136+
default: Option<Default<'tcx>>) -> ty::TyVid {
118137
let index = self.values.push(TypeVariableData {
119-
value: Bounded(vec![]),
138+
value: Bounded { relations: vec![], default: default },
120139
diverging: diverging
121140
});
122141
ty::TyVid { index: index as u32 }
123142
}
124143

125144
pub fn probe(&self, vid: ty::TyVid) -> Option<Ty<'tcx>> {
126145
match self.values.get(vid.index as usize).value {
127-
Bounded(..) => None,
146+
Bounded { .. } => None,
128147
Known(t) => Some(t)
129148
}
130149
}
@@ -197,12 +216,14 @@ impl<'tcx> TypeVariableTable<'tcx> {
197216
}
198217

199218
pub fn unsolved_variables(&self) -> Vec<ty::TyVid> {
200-
self.values.iter().enumerate().filter_map(|(i, value)|
201-
match &value.value {
219+
self.values
220+
.iter()
221+
.enumerate()
222+
.filter_map(|(i, value)| match &value.value {
202223
&TypeVariableValue::Known(_) => None,
203-
&TypeVariableValue::Bounded(_) => Some(ty::TyVid { index: i as u32 })
204-
}
205-
).collect()
224+
&TypeVariableValue::Bounded { .. } => Some(ty::TyVid { index: i as u32 })
225+
})
226+
.collect()
206227
}
207228
}
208229

@@ -213,7 +234,7 @@ impl<'tcx> sv::SnapshotVecDelegate for Delegate<'tcx> {
213234
fn reverse(values: &mut Vec<TypeVariableData<'tcx>>, action: UndoEntry) {
214235
match action {
215236
SpecifyVar(vid, relations) => {
216-
values[vid.index as usize].value = Bounded(relations);
237+
values[vid.index as usize].value = Bounded { relations: relations, default: None };
217238
}
218239

219240
Relate(a, b) => {
@@ -227,6 +248,6 @@ impl<'tcx> sv::SnapshotVecDelegate for Delegate<'tcx> {
227248
fn relations<'a>(v: &'a mut TypeVariableData) -> &'a mut Vec<Relation> {
228249
match v.value {
229250
Known(_) => panic!("var_sub_var: variable is known"),
230-
Bounded(ref mut relations) => relations
251+
Bounded { ref mut relations, .. } => relations
231252
}
232253
}

branches/beta/src/librustc_typeck/check/mod.rs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ use fmt_macros::{Parser, Piece, Position};
8787
use middle::astconv_util::{check_path_args, NO_TPS, NO_REGIONS};
8888
use middle::def;
8989
use middle::infer;
90+
use middle::infer::type_variable;
9091
use middle::pat_util::{self, pat_id_map};
9192
use middle::privacy::{AllPublic, LastMod};
9293
use middle::region::{self, CodeExtent};
@@ -1139,12 +1140,8 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
11391140
}
11401141

11411142
fn ty_infer(&self, default: Option<Ty<'tcx>>, _span: Span) -> Ty<'tcx> {
1142-
let ty_var = self.infcx().next_ty_var();
1143-
match default {
1144-
Some(default) => { self.infcx().defaults.borrow_mut().insert(ty_var, default); }
1145-
None => {}
1146-
}
1147-
ty_var
1143+
let default = default.map(|t| type_variable::Default { ty: t });
1144+
self.infcx().next_ty_var_with_default(default)
11481145
}
11491146

11501147
fn projected_ty_from_poly_trait_ref(&self,
@@ -1697,7 +1694,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16971694
fn select_all_obligations_and_apply_defaults(&self) {
16981695
use middle::ty::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat, Neither};
16991696

1700-
debug!("select_all_obligations_and_apply_defaults: defaults={:?}", self.infcx().defaults);
1697+
// debug!("select_all_obligations_and_apply_defaults: defaults={:?}", self.infcx().defaults);
17011698

17021699
for _ in (0..self.tcx().sess.recursion_limit.get()) {
17031700
self.select_obligations_where_possible();
@@ -1725,11 +1722,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17251722

17261723
// Collect the set of variables that need fallback applied
17271724
for ty in &unsolved_variables {
1728-
if self.inh.infcx.defaults.borrow().contains_key(ty) {
1725+
if let Some(_) = self.inh.infcx.default(ty) {
17291726
let resolved = self.infcx().resolve_type_vars_if_possible(ty);
17301727

1731-
debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1732-
ty, self.inh.infcx.defaults.borrow().get(ty));
1728+
// debug!("select_all_obligations_and_apply_defaults: ty: {:?} with default: {:?}",
1729+
// ty, self.inh.infcx.defaults.borrow().get(ty));
17331730

17341731
match resolved.sty {
17351732
ty::TyInfer(ty::TyVar(_)) => {
@@ -1754,7 +1751,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17541751

17551752
// Go through the unbound variables and unify them with the proper fallbacks
17561753
for ty in &unbound_tyvars {
1757-
// let resolved = self.infcx().resolve_type_vars_if_possible(ty);
17581754
if self.infcx().type_var_diverges(ty) {
17591755
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
17601756
} else {
@@ -1766,17 +1762,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17661762
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
17671763
}
17681764
Neither => {
1769-
let default_map = self.inh.infcx.defaults.borrow();
1770-
if let Some(default) = default_map.get(ty) {
1765+
if let Some(default) = self.inh.infcx.default(ty) {
17711766
match infer::mk_eqty(self.infcx(), false,
17721767
infer::Misc(codemap::DUMMY_SP),
1773-
ty, default) {
1768+
ty, default.ty) {
17741769
Ok(()) => { /* ok */ }
17751770
Err(_) => {
17761771
self.infcx().report_conflicting_default_types(
17771772
codemap::DUMMY_SP,
17781773
ty,
1779-
default)
1774+
default.ty)
17801775
}
17811776
}
17821777
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use std::marker::PhantomData;
2+
3+
trait Id {
4+
type This;
5+
}
6+
7+
impl<A> Id for A {
8+
type This = A;
9+
}
10+
11+
struct Foo<X: Default = usize, Y = <X as Id>::This> {
12+
data: PhantomData<(X, Y)>
13+
}
14+
15+
impl<X: Default, Y> Foo<X, Y> {
16+
fn new() -> Foo<X, Y> {
17+
Foo { data: PhantomData }
18+
}
19+
}
20+
21+
fn main() {
22+
let foo = Foo::new();
23+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use std::marker::PhantomData;
2+
3+
struct Foo<T,U=T> { data: PhantomData<(T, U)> }
4+
5+
fn main() {
6+
let foo = Foo { data: PhantomData };
7+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use std::marker::PhantomData;
2+
3+
trait TypeEq<A> {}
4+
impl<A> TypeEq<A> for A {}
5+
6+
struct DeterministicHasher;
7+
struct RandomHasher;
8+
9+
10+
struct MyHashMap<K, V, H=DeterministicHasher> {
11+
data: PhantomData<(K, V, H)>
12+
}
13+
14+
impl<K, V, H> MyHashMap<K, V, H> {
15+
fn new() -> MyHashMap<K, V, H> {
16+
MyHashMap { data: PhantomData }
17+
}
18+
}
19+
20+
mod mystd {
21+
use super::{MyHashMap, RandomHasher};
22+
pub type HashMap<K, V, H=RandomHasher> = MyHashMap<K, V, H>;
23+
}
24+
25+
fn try_me<H>(hash_map: mystd::HashMap<i32, i32, H>) {}
26+
27+
fn main() {
28+
let hash_map = mystd::HashMap::new();
29+
try_me(hash_map);
30+
}

0 commit comments

Comments
 (0)