Skip to content

Commit 505e423

Browse files
committed
---
yaml --- r: 64668 b: refs/heads/snap-stage3 c: e75ec80 h: refs/heads/master v: v3
1 parent f2637ba commit 505e423

File tree

2 files changed

+47
-25
lines changed

2 files changed

+47
-25
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 2d28d645422c1617be58c8ca7ad9a457264ca850
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: fbbbc98ea4aaa59c7266ab4b60f18050a046634e
4+
refs/heads/snap-stage3: e75ec8015701d4a43ec2644dbbc4a2e051c4f515
55
refs/heads/try: 7b78b52e602bb3ea8174f9b2006bff3315f03ef9
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/librustc/middle/typeck/check/vtable.rs

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ use syntax::visit;
4545
// *fully* resolved. (We could be less restrictive than that, but it
4646
// would require much more care, and this seems to work decently in
4747
// practice.)
48+
//
49+
// While resolution on a single type requires the type to be fully
50+
// resolved, when resolving a substitution against a list of bounds,
51+
// we do not require all of the types to be resolved in advance.
52+
// Furthermore, we process substitutions in reverse order, which
53+
// allows resolution on later parameters to give information on
54+
// earlier params referenced by the typeclass bounds.
55+
// It may be better to do something more clever, like processing fully
56+
// resolved types first.
57+
4858

4959
/// Location info records the span and ID of the expression or item that is
5060
/// responsible for this vtable instantiation. (This may not be an expression
@@ -83,11 +93,19 @@ fn lookup_vtables(vcx: &VtableContext,
8393
substs.repr(vcx.tcx()));
8494
let _i = indenter();
8595

86-
let mut result = ~[];
87-
for substs.tps.iter().zip(type_param_defs.iter()).advance |(ty, def)| {
88-
result.push(lookup_vtables_for_param(vcx, location_info, Some(substs),
89-
&*def.bounds, *ty, is_early));
90-
}
96+
97+
// We do this backwards for reasons discussed above.
98+
assert_eq!(substs.tps.len(), type_param_defs.len());
99+
let mut result =
100+
substs.tps.rev_iter()
101+
.zip(type_param_defs.rev_iter())
102+
.transform(|(ty, def)|
103+
lookup_vtables_for_param(vcx, location_info, Some(substs),
104+
&*def.bounds, *ty, is_early))
105+
.to_owned_vec();
106+
result.reverse();
107+
108+
assert_eq!(substs.tps.len(), result.len());
91109
debug!("lookup_vtables result(\
92110
location_info=%?, \
93111
type_param_defs=%s, \
@@ -198,8 +216,7 @@ fn relate_trait_refs(vcx: &VtableContext,
198216
}
199217
}
200218

201-
// Look up the vtable to use when treating an item of type `t` as if it has
202-
// type `trait_ty`
219+
// Look up the vtable implementing the trait `trait_ref` at type `t`
203220
fn lookup_vtable(vcx: &VtableContext,
204221
location_info: &LocationInfo,
205222
ty: ty::t,
@@ -261,13 +278,14 @@ fn lookup_vtable(vcx: &VtableContext,
261278
}
262279
}
263280

264-
_ => {
265-
return search_for_vtable(vcx, location_info,
266-
ty, trait_ref, is_early)
267-
}
281+
// Default case just falls through
282+
_ => { }
268283
}
269284

270-
return None;
285+
// If we aren't a self type or param, or it was, but we didn't find it,
286+
// do a search.
287+
return search_for_vtable(vcx, location_info,
288+
ty, trait_ref, is_early)
271289
}
272290

273291
fn search_for_vtable(vcx: &VtableContext,
@@ -359,16 +377,23 @@ fn search_for_vtable(vcx: &VtableContext,
359377
let of_trait_ref = of_trait_ref.subst(tcx, &substs);
360378
relate_trait_refs(vcx, location_info, of_trait_ref, trait_ref);
361379

380+
362381
// Recall that trait_ref -- the trait type we're casting to --
363382
// is the trait with id trait_ref.def_id applied to the substs
364-
// trait_ref.substs. Now we extract out the types themselves
365-
// from trait_ref.substs.
383+
// trait_ref.substs.
384+
385+
// Resolve any sub bounds. Note that there still may be free
386+
// type variables in substs. This might still be OK: the
387+
// process of looking up bounds might constrain some of them.
388+
let im_generics =
389+
ty::lookup_item_type(tcx, im.did).generics;
390+
let subres = lookup_vtables(vcx, location_info,
391+
*im_generics.type_param_defs, &substs,
392+
is_early);
366393

367-
// Recall that substs is the impl self type's list of
368-
// substitutions. That is, if this is an impl of some trait
369-
// for foo<T, U>, then substs is [T, U]. substs might contain
370-
// type variables, so we call fixup_substs to resolve them.
371394

395+
// substs might contain type variables, so we call
396+
// fixup_substs to resolve them.
372397
let substs_f = match fixup_substs(vcx,
373398
location_info,
374399
trait_ref.def_id,
@@ -392,13 +417,10 @@ fn search_for_vtable(vcx: &VtableContext,
392417
// ty with the substitutions from the trait type that we're
393418
// trying to cast to. connect_trait_tps requires these lists
394419
// of types to unify pairwise.
395-
396-
let im_generics =
397-
ty::lookup_item_type(tcx, im.did).generics;
420+
// I am a little confused about this, since it seems to be
421+
// very similar to the relate_trait_refs we already do,
422+
// but problems crop up if it is removed, so... -sully
398423
connect_trait_tps(vcx, location_info, &substs_f, trait_ref, im.did);
399-
let subres = lookup_vtables(vcx, location_info,
400-
*im_generics.type_param_defs, &substs_f,
401-
is_early);
402424

403425
// Finally, we register that we found a matching impl, and
404426
// record the def ID of the impl as well as the resolved list

0 commit comments

Comments
 (0)