Skip to content

Commit 9e0c596

Browse files
committed
rustc: Eliminate the necessity of having an expr in order to call lookup_vtables(). rs=#rust
Automatically-generated derived methods don't have exprs and need to call this function.
1 parent e2f33e6 commit 9e0c596

File tree

3 files changed

+80
-44
lines changed

3 files changed

+80
-44
lines changed

src/rustc/middle/typeck/check.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ use typeck::infer::{resolve_type, force_tvar};
7878
use result::{Result, Ok, Err};
7979
use syntax::print::pprust;
8080
use syntax::parse::token::special_idents;
81+
use vtable::LocationInfo;
8182

8283
use std::map::HashMap;
8384

@@ -865,7 +866,8 @@ fn check_expr(fcx: @fn_ctxt, expr: @ast::expr,
865866
// would return ($0, $1) where $0 and $1 are freshly instantiated type
866867
// variables.
867868
fn impl_self_ty(fcx: @fn_ctxt,
868-
expr: @ast::expr, // (potential) receiver for this impl
869+
location_info: &LocationInfo, // (potential) receiver for
870+
// this impl
869871
did: ast::def_id) -> ty_param_substs_and_ty {
870872
let tcx = fcx.ccx.tcx;
871873

@@ -902,7 +904,8 @@ fn impl_self_ty(fcx: @fn_ctxt,
902904
};
903905

904906
let self_r = if region_param.is_some() {
905-
Some(fcx.infcx().next_region_var(expr.span, expr.id))
907+
Some(fcx.infcx().next_region_var(location_info.span,
908+
location_info.id))
906909
} else {
907910
None
908911
};

src/rustc/middle/typeck/check/method.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,8 +491,9 @@ impl LookupContext {
491491

492492
// determine the `self` of the impl with fresh
493493
// variables for each parameter:
494+
let location_info = &vtable::location_info_for_expr(self.self_expr);
494495
let {substs: impl_substs, ty: impl_ty} =
495-
impl_self_ty(self.fcx, self.self_expr, impl_info.did);
496+
impl_self_ty(self.fcx, location_info, impl_info.did);
496497

497498
let (impl_ty, impl_substs) =
498499
self.create_rcvr_ty_and_substs_for_method(

src/rustc/middle/typeck/check/vtable.rs

Lines changed: 73 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use check::{fn_ctxt, impl_self_ty};
22
use infer::{resolve_type, resolve_and_force_all_but_regions,
33
fixup_err_to_str};
4+
use syntax::codemap::span;
45
use syntax::print::pprust;
56
use result::{Result, Ok, Err};
67
use util::common::indenter;
@@ -21,6 +22,14 @@ use util::common::indenter;
2122
// would require much more care, and this seems to work decently in
2223
// practice.)
2324

25+
/// Location info records the span and ID of the expression or item that is
26+
/// responsible for this vtable instantiation. (This may not be an expression
27+
/// if the vtable instantiation is being performed as part of "deriving".)
28+
struct LocationInfo {
29+
span: span,
30+
id: ast::node_id
31+
}
32+
2433
fn has_trait_bounds(tps: ~[ty::param_bounds]) -> bool {
2534
vec::any(tps, |bs| {
2635
bs.any(|b| {
@@ -30,16 +39,16 @@ fn has_trait_bounds(tps: ~[ty::param_bounds]) -> bool {
3039
}
3140

3241
fn lookup_vtables(fcx: @fn_ctxt,
33-
expr: @ast::expr,
42+
location_info: &LocationInfo,
3443
bounds: @~[ty::param_bounds],
3544
substs: &ty::substs,
3645
allow_unsafe: bool,
3746
is_early: bool) -> vtable_res
3847
{
39-
debug!("lookup_vtables(expr=%?/%s, \
48+
debug!("lookup_vtables(location_info=%?,
4049
# bounds=%?, \
4150
substs=%s",
42-
expr.id, fcx.expr_to_str(expr),
51+
location_info,
4352
bounds.len(),
4453
ty::substs_to_str(fcx.tcx(), substs));
4554
let _i = indenter();
@@ -51,12 +60,12 @@ fn lookup_vtables(fcx: @fn_ctxt,
5160
match *bound {
5261
ty::bound_trait(i_ty) => {
5362
let i_ty = ty::subst(tcx, substs, i_ty);
54-
match lookup_vtable_covariant(fcx, expr, *ty, i_ty,
63+
match lookup_vtable_covariant(fcx, location_info, *ty, i_ty,
5564
allow_unsafe, is_early) {
5665
Some(vtable) => result.push(vtable),
5766
None => {
5867
fcx.tcx().sess.span_fatal(
59-
expr.span,
68+
location_info.span,
6069
fmt!("failed to find an implementation of trait \
6170
%s for %s",
6271
ty_to_str(fcx.tcx(), i_ty),
@@ -72,29 +81,29 @@ fn lookup_vtables(fcx: @fn_ctxt,
7281
@result
7382
}
7483

75-
fn fixup_substs(fcx: @fn_ctxt, expr: @ast::expr,
84+
fn fixup_substs(fcx: @fn_ctxt, location_info: &LocationInfo,
7685
id: ast::def_id, substs: ty::substs,
7786
is_early: bool) -> Option<ty::substs> {
7887
let tcx = fcx.ccx.tcx;
7988
// use a dummy type just to package up the substs that need fixing up
8089
let t = ty::mk_trait(tcx, id, substs, ty::vstore_slice(ty::re_static));
81-
do fixup_ty(fcx, expr, t, is_early).map |t_f| {
90+
do fixup_ty(fcx, location_info, t, is_early).map |t_f| {
8291
match ty::get(*t_f).sty {
8392
ty::ty_trait(_, substs_f, _) => substs_f,
8493
_ => fail ~"t_f should be a trait"
8594
}
8695
}
8796
}
8897

89-
fn relate_trait_tys(fcx: @fn_ctxt, expr: @ast::expr,
98+
fn relate_trait_tys(fcx: @fn_ctxt, location_info: &LocationInfo,
9099
exp_trait_ty: ty::t, act_trait_ty: ty::t) {
91-
demand::suptype(fcx, expr.span, exp_trait_ty, act_trait_ty)
100+
demand::suptype(fcx, location_info.span, exp_trait_ty, act_trait_ty)
92101
}
93102

94103
// Look up the vtable to use when treating an item of type `t` as if it has
95104
// type `trait_ty`. This does allow subtraits.
96105
fn lookup_vtable_covariant(fcx: @fn_ctxt,
97-
expr: @ast::expr,
106+
location_info: &LocationInfo,
98107
ty: ty::t,
99108
trait_ty: ty::t,
100109
allow_unsafe: bool,
@@ -108,7 +117,7 @@ fn lookup_vtable_covariant(fcx: @fn_ctxt,
108117
worklist.push(trait_ty);
109118
while worklist.len() > 0 {
110119
let trait_ty = worklist.pop();
111-
let result = lookup_vtable_invariant(fcx, expr, ty, trait_ty,
120+
let result = lookup_vtable_invariant(fcx, location_info, ty, trait_ty,
112121
allow_unsafe, is_early);
113122
if result.is_some() {
114123
return result;
@@ -136,7 +145,7 @@ fn lookup_vtable_covariant(fcx: @fn_ctxt,
136145
}
137146
}
138147
_ => {
139-
fcx.ccx.tcx.sess.impossible_case(expr.span,
148+
fcx.ccx.tcx.sess.impossible_case(location_info.span,
140149
"lookup_vtable_covariant: \
141150
non-trait in worklist");
142151
}
@@ -149,7 +158,7 @@ fn lookup_vtable_covariant(fcx: @fn_ctxt,
149158
// Look up the vtable to use when treating an item of type `t` as if it has
150159
// type `trait_ty`. This does not allow subtraits.
151160
fn lookup_vtable_invariant(fcx: @fn_ctxt,
152-
expr: @ast::expr,
161+
location_info: &LocationInfo,
153162
ty: ty::t,
154163
trait_ty: ty::t,
155164
allow_unsafe: bool,
@@ -162,11 +171,11 @@ fn lookup_vtable_invariant(fcx: @fn_ctxt,
162171
let tcx = fcx.ccx.tcx;
163172
let (trait_id, trait_substs, trait_vstore) = match ty::get(trait_ty).sty {
164173
ty::ty_trait(did, substs, vstore) => (did, substs, vstore),
165-
_ => tcx.sess.impossible_case(expr.span,
174+
_ => tcx.sess.impossible_case(location_info.span,
166175
"lookup_vtable_invariant: \
167176
don't know how to handle a non-trait")
168177
};
169-
let ty = match fixup_ty(fcx, expr, ty, is_early) {
178+
let ty = match fixup_ty(fcx, location_info, ty, is_early) {
170179
Some(ty) => ty,
171180
None => {
172181
// fixup_ty can only fail if this is early resolution
@@ -194,13 +203,13 @@ fn lookup_vtable_invariant(fcx: @fn_ctxt,
194203
debug!("(checking vtable) @0 relating \
195204
ty to trait ty with did %?",
196205
idid);
197-
relate_trait_tys(fcx, expr,
206+
relate_trait_tys(fcx, location_info,
198207
trait_ty, ity);
199208
return Some(vtable_param(n, n_bound));
200209
}
201210
}
202211
_ => tcx.sess.impossible_case(
203-
expr.span,
212+
location_info.span,
204213
"lookup_vtable_invariant: in loop, \
205214
don't know how to handle a non-trait ity")
206215
}
@@ -214,17 +223,17 @@ fn lookup_vtable_invariant(fcx: @fn_ctxt,
214223
debug!("(checking vtable) @1 relating ty to trait ty with did %?",
215224
did);
216225

217-
relate_trait_tys(fcx, expr, trait_ty, ty);
226+
relate_trait_tys(fcx, location_info, trait_ty, ty);
218227
if !allow_unsafe && !is_early {
219228
for vec::each(*ty::trait_methods(tcx, did)) |m| {
220229
if ty::type_has_self(ty::mk_fn(tcx, m.fty)) {
221230
tcx.sess.span_err(
222-
expr.span,
231+
location_info.span,
223232
~"a boxed trait with self types may not be \
224233
passed as a bounded type");
225234
} else if (*m.tps).len() > 0u {
226235
tcx.sess.span_err(
227-
expr.span,
236+
location_info.span,
228237
~"a boxed trait with generic methods may not \
229238
be passed as a bounded type");
230239

@@ -300,10 +309,11 @@ fn lookup_vtable_invariant(fcx: @fn_ctxt,
300309
// to some_trait. If not, then we try the next
301310
// impl.
302311
let {substs: substs, ty: for_ty} =
303-
impl_self_ty(fcx, expr, im.did);
312+
impl_self_ty(fcx, location_info, im.did);
304313
let im_bs = ty::lookup_item_type(tcx,
305314
im.did).bounds;
306-
match fcx.mk_subty(false, expr.span, ty, for_ty) {
315+
match fcx.mk_subty(false, location_info.span, ty,
316+
for_ty) {
307317
result::Err(_) => loop,
308318
result::Ok(()) => ()
309319
}
@@ -334,7 +344,8 @@ fn lookup_vtable_invariant(fcx: @fn_ctxt,
334344
fcx.infcx().ty_to_str(trait_ty),
335345
fcx.infcx().ty_to_str(*of_ty));
336346
let of_ty = ty::subst(tcx, &substs, *of_ty);
337-
relate_trait_tys(fcx, expr, trait_ty, of_ty);
347+
relate_trait_tys(fcx, location_info, trait_ty,
348+
of_ty);
338349

339350
// Recall that trait_ty -- the trait type
340351
// we're casting to -- is the trait with
@@ -357,7 +368,7 @@ fn lookup_vtable_invariant(fcx: @fn_ctxt,
357368
// resolve them.
358369

359370
let substs_f = match fixup_substs(fcx,
360-
expr,
371+
location_info,
361372
trait_id,
362373
substs,
363374
is_early) {
@@ -382,11 +393,14 @@ fn lookup_vtable_invariant(fcx: @fn_ctxt,
382393
// to. connect_trait_tps requires these
383394
// lists of types to unify pairwise.
384395

385-
connect_trait_tps(fcx, expr, substs_f.tps,
386-
trait_tps, im.did,
396+
connect_trait_tps(fcx,
397+
location_info,
398+
substs_f.tps,
399+
trait_tps,
400+
im.did,
387401
trait_vstore);
388402
let subres = lookup_vtables(
389-
fcx, expr, im_bs, &substs_f,
403+
fcx, location_info, im_bs, &substs_f,
390404
false, is_early);
391405

392406
// Finally, we register that we found a
@@ -408,7 +422,7 @@ fn lookup_vtable_invariant(fcx: @fn_ctxt,
408422
_ => {
409423
if !is_early {
410424
fcx.ccx.tcx.sess.span_err(
411-
expr.span,
425+
location_info.span,
412426
~"multiple applicable methods in scope");
413427
}
414428
return Some(found[0]);
@@ -421,7 +435,7 @@ fn lookup_vtable_invariant(fcx: @fn_ctxt,
421435
}
422436

423437
fn fixup_ty(fcx: @fn_ctxt,
424-
expr: @ast::expr,
438+
location_info: &LocationInfo,
425439
ty: ty::t,
426440
is_early: bool) -> Option<ty::t>
427441
{
@@ -430,7 +444,7 @@ fn fixup_ty(fcx: @fn_ctxt,
430444
Ok(new_type) => Some(new_type),
431445
Err(e) if !is_early => {
432446
tcx.sess.span_fatal(
433-
expr.span,
447+
location_info.span,
434448
fmt!("cannot determine a type \
435449
for this bounded type parameter: %s",
436450
fixup_err_to_str(e)))
@@ -441,8 +455,11 @@ fn fixup_ty(fcx: @fn_ctxt,
441455
}
442456
}
443457

444-
fn connect_trait_tps(fcx: @fn_ctxt, expr: @ast::expr, impl_tys: ~[ty::t],
445-
trait_tys: ~[ty::t], impl_did: ast::def_id,
458+
fn connect_trait_tps(fcx: @fn_ctxt,
459+
location_info: &LocationInfo,
460+
impl_tys: ~[ty::t],
461+
trait_tys: ~[ty::t],
462+
impl_did: ast::def_id,
446463
vstore: ty::vstore) {
447464
let tcx = fcx.ccx.tcx;
448465

@@ -454,10 +471,10 @@ fn connect_trait_tps(fcx: @fn_ctxt, expr: @ast::expr, impl_tys: ~[ty::t],
454471
match ty::get(trait_ty).sty {
455472
ty::ty_trait(_, substs, _) => {
456473
for vec::each2(substs.tps, trait_tys) |a, b| {
457-
demand::suptype(fcx, expr.span, *a, *b)
474+
demand::suptype(fcx, location_info.span, *a, *b)
458475
}
459476
}
460-
_ => tcx.sess.impossible_case(expr.span, "connect_trait_tps: \
477+
_ => tcx.sess.impossible_case(location_info.span, "connect_trait_tps: \
461478
don't know how to handle a non-trait ty")
462479
}
463480
}
@@ -469,6 +486,13 @@ fn insert_vtables(ccx: @crate_ctxt, callee_id: ast::node_id,
469486
ccx.vtable_map.insert(callee_id, vtables);
470487
}
471488

489+
fn location_info_for_expr(expr: @ast::expr) -> LocationInfo {
490+
LocationInfo {
491+
span: expr.span,
492+
id: expr.id
493+
}
494+
}
495+
472496
fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
473497
debug!("vtable: early_resolve_expr() ex with id %? (early: %b): %s",
474498
ex.id, is_early, expr_to_str(ex, fcx.tcx().sess.intr()));
@@ -489,8 +513,9 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
489513
%s",
490514
ty::param_bounds_to_str(fcx.tcx(), *bounds));
491515
}
492-
let vtbls = lookup_vtables(fcx, ex, item_ty.bounds,
493-
substs, false, is_early);
516+
let vtbls = lookup_vtables(fcx, &location_info_for_expr(ex),
517+
item_ty.bounds, substs, false,
518+
is_early);
494519
if !is_early { cx.vtable_map.insert(ex.id, vtbls); }
495520
}
496521
}
@@ -514,8 +539,8 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
514539
_ => ex.callee_id
515540
};
516541
let substs = fcx.node_ty_substs(callee_id);
517-
let vtbls = lookup_vtables(fcx, ex, bounds,
518-
&substs, false, is_early);
542+
let vtbls = lookup_vtables(fcx, &location_info_for_expr(ex),
543+
bounds, &substs, false, is_early);
519544
if !is_early {
520545
insert_vtables(cx, callee_id, vtbls);
521546
}
@@ -534,8 +559,13 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
534559
// XXX: This is invariant and shouldn't be. --pcw
535560

536561
let ty = fcx.expr_ty(src);
537-
let vtable_opt = lookup_vtable_invariant(fcx, ex, ty, target_ty,
538-
true, is_early);
562+
let vtable_opt =
563+
lookup_vtable_invariant(fcx,
564+
&location_info_for_expr(ex),
565+
ty,
566+
target_ty,
567+
true,
568+
is_early);
539569
match vtable_opt {
540570
None => {
541571
// Try the new-style boxed trait; "@int as @Trait".
@@ -553,9 +583,11 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
553583
(ty::ty_box(_), ty::vstore_box) |
554584
(ty::ty_uniq(_), ty::vstore_uniq) |
555585
(ty::ty_rptr(*), ty::vstore_slice(*)) => {
586+
let location_info =
587+
&location_info_for_expr(ex);
556588
let vtable_opt =
557589
lookup_vtable_invariant(fcx,
558-
ex,
590+
location_info,
559591
mt.ty,
560592
target_ty,
561593
true,

0 commit comments

Comments
 (0)