Skip to content

Commit ced2600

Browse files
committed
Remove default data from TypeVariableValue::Bounded.
We use the default information in TypeVariableData. Also improved some comments.
1 parent 9a98d23 commit ced2600

File tree

2 files changed

+36
-23
lines changed

2 files changed

+36
-23
lines changed

src/librustc/infer/type_variable.rs

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

8181
enum TypeVariableValue<'tcx> {
8282
Known(Ty<'tcx>),
83-
Bounded {
84-
default: Option<Default<'tcx>>
85-
}
83+
Bounded,
8684
}
8785

8886
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
@@ -112,9 +110,8 @@ pub struct Snapshot {
112110
sub_snapshot: ut::Snapshot<ty::TyVid>,
113111
}
114112

115-
struct Instantiate<'tcx> {
113+
struct Instantiate {
116114
vid: ty::TyVid,
117-
default: Option<Default<'tcx>>,
118115
}
119116

120117
struct Delegate<'tcx>(PhantomData<&'tcx ()>);
@@ -175,8 +172,8 @@ impl<'tcx> TypeVariableTable<'tcx> {
175172
};
176173

177174
match old_value {
178-
TypeVariableValue::Bounded { default } => {
179-
self.values.record(Instantiate { vid: vid, default: default });
175+
TypeVariableValue::Bounded => {
176+
self.values.record(Instantiate { vid: vid });
180177
}
181178
TypeVariableValue::Known(old_ty) => {
182179
bug!("instantiating type variable `{:?}` twice: new-value = {:?}, old-value={:?}",
@@ -201,7 +198,7 @@ impl<'tcx> TypeVariableTable<'tcx> {
201198
};
202199

203200
let index = self.values.push(TypeVariableData {
204-
value: Bounded { default: Some(default.clone()) },
201+
value: Bounded,
205202
origin,
206203
default,
207204
});
@@ -253,7 +250,7 @@ impl<'tcx> TypeVariableTable<'tcx> {
253250
pub fn probe_root(&mut self, vid: ty::TyVid) -> Option<Ty<'tcx>> {
254251
debug_assert!(self.root_var(vid) == vid);
255252
match self.values.get(vid.index as usize).value {
256-
Bounded { .. } => None,
253+
Bounded => None,
257254
Known(t) => Some(t)
258255
}
259256
}
@@ -349,12 +346,12 @@ impl<'tcx> TypeVariableTable<'tcx> {
349346
debug!("NewElem({}) new_elem_threshold={}", index, new_elem_threshold);
350347
}
351348

352-
sv::UndoLog::Other(Instantiate { vid, .. }) => {
349+
sv::UndoLog::Other(Instantiate { vid }) => {
353350
if vid.index < new_elem_threshold {
354351
// quick check to see if this variable was
355352
// created since the snapshot started or not.
356353
let escaping_type = match self.values.get(vid.index as usize).value {
357-
Bounded { .. } => bug!(),
354+
Bounded => bug!(),
358355
Known(ty) => ty,
359356
};
360357
escaping_types.push(escaping_type);
@@ -385,12 +382,10 @@ impl<'tcx> TypeVariableTable<'tcx> {
385382

386383
impl<'tcx> sv::SnapshotVecDelegate for Delegate<'tcx> {
387384
type Value = TypeVariableData<'tcx>;
388-
type Undo = Instantiate<'tcx>;
385+
type Undo = Instantiate;
389386

390-
fn reverse(values: &mut Vec<TypeVariableData<'tcx>>, action: Instantiate<'tcx>) {
391-
let Instantiate { vid, default } = action;
392-
values[vid.index as usize].value = Bounded {
393-
default,
394-
};
387+
fn reverse(values: &mut Vec<TypeVariableData<'tcx>>, action: Instantiate) {
388+
let Instantiate { vid } = action;
389+
values[vid.index as usize].value = Bounded;
395390
}
396391
}

src/librustc_typeck/check/mod.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2178,12 +2178,28 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
21782178
}
21792179
}
21802180

2181+
/// This runs as the last resort of type inference.
2182+
///
2183+
/// It applies user supplied defaults as fallbacks for inference variables,
2184+
/// for example in `fn foo<T=String>()` an inference variable originated from `T`
2185+
/// will have `String` as its default.
2186+
///
2187+
/// Adding a default to a type parameter that has none should be backwards compatible.
2188+
/// However if we get conflicting defaults we do not know how to resolve them.
2189+
/// Therefore we must future-proof against such a conflict by not allowing
2190+
/// type variables with defaults to unify with type variables without defaults.
2191+
///
2192+
/// We may come up with rules to prioritize a type parameter over another.
2193+
/// When unifying type variables, the highest priority parameter involved
2194+
/// has the final say on what the default should be.
2195+
/// Currently we prioritize defaults from impls and fns over defaults in types,
2196+
/// this for example allows `fn foo<T=String>(x: Option<T>)` to work
2197+
/// even though `Option<T>` has no default for `T`.
21812198
fn apply_user_type_parameter_fallback(&self) {
21822199
use self::TypeVariableOrigin::TypeParameterDefinition;
21832200
use ty::OriginOfTyParam;
2184-
21852201
// Collect variables that are unsolved and support fallback,
2186-
// grouped by subtyping equivalence.
2202+
// grouped in bags by subtyping equivalence.
21872203
let mut bags = FxHashMap();
21882204
for vid in self.fulfillment_cx.borrow().vars_in_unsolved_obligations() {
21892205
let mut type_variables = self.infcx.type_variables.borrow_mut();
@@ -2199,9 +2215,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
21992215
bags.entry(root).or_insert(Vec::new()).push(vid);
22002216
}
22012217
}
2202-
2218+
// A bag will successfuly fallback to a default if all of it's variables
2219+
// have a default, and that default is the same.
2220+
// Low priority variables will be ignored in the presence of higher priority variables.
22032221
'bags: for (_, mut bag) in bags.into_iter() {
2204-
// Partition the bag by the origin of the default.
2222+
// Partition the bag by the origin of the type param.
22052223
let (fn_or_impl, ty_def) = bag.into_iter().partition(|&v| {
22062224
match self.infcx.type_variables.borrow().var_origin(v) {
22072225
TypeParameterDefinition(_, _, OriginOfTyParam::Fn) |
@@ -2212,7 +2230,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
22122230
});
22132231
// Params from fns or impls take priority, if they exist ignore the rest of the bag.
22142232
bag = fn_or_impl;
2215-
if bag.is_empty() {
2233+
if bag.is_empty() {
22162234
bag = ty_def;
22172235
}
22182236
// For future-proofing against conflicting defaults,
@@ -2233,7 +2251,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
22332251
let normalized_default = self.normalize_associated_types_in(
22342252
user_default.origin_span,
22352253
&user_default.ty);
2236-
// QUESTION(leodasvacas):
2254+
// QUESTION(leodasvacas):
22372255
// This will emit "expected type mismatch" on conflicting defaults, which is bad.
22382256
// I'd be happy to somehow detect or rollback this demand on conflict defaults
22392257
// so we would emit "type annotations needed" instead.

0 commit comments

Comments
 (0)