Skip to content

Commit 3f7c74d

Browse files
committed
auto merge of #5467 : nikomatsakis/rust/issues-3888-4036-4492-cannot-encode-region-variables, r=nikomatsakis
The basic problem was that vtables were not being resolved. The fix uncovered another issue, which was that the syntax extensions were not creating method calls properly and were relying on outdated code in typeck, so I fixed that too. Resolves issues #3888, #4036, #4492. r? @catamorphism
2 parents bbc4ca1 + 3ca7c22 commit 3f7c74d

File tree

19 files changed

+276
-207
lines changed

19 files changed

+276
-207
lines changed

src/librustc/middle/trans/base.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1579,7 +1579,17 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext,
15791579
id: ast::node_id,
15801580
impl_id: Option<ast::def_id>,
15811581
param_substs: Option<@param_substs>,
1582-
sp: Option<span>) -> fn_ctxt {
1582+
sp: Option<span>) -> fn_ctxt
1583+
{
1584+
for param_substs.each |p| { p.validate(); }
1585+
1586+
debug!("new_fn_ctxt_w_id(path=%s, id=%?, impl_id=%?, \
1587+
param_substs=%s",
1588+
path_str(ccx.sess, path),
1589+
id,
1590+
impl_id,
1591+
opt_param_substs_to_str(ccx.tcx, &param_substs));
1592+
15831593
let llbbs = mk_standard_basic_blocks(llfndecl);
15841594
return @mut fn_ctxt_ {
15851595
llfn: llfndecl,

src/librustc/middle/trans/callee.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ pub fn trans_fn_ref_with_vtables(
217217
// - `type_params`: values for each of the fn/method's type parameters
218218
// - `vtables`: values for each bound on each of the type parameters
219219

220-
let _icx = bcx.insn_ctxt("trans_fn_with_vtables");
220+
let _icx = bcx.insn_ctxt("trans_fn_ref_with_vtables");
221221
let ccx = bcx.ccx();
222222
let tcx = ccx.tcx;
223223

@@ -228,6 +228,8 @@ pub fn trans_fn_ref_with_vtables(
228228
vtables);
229229
let _indenter = indenter();
230230

231+
fail_unless!(type_params.all(|t| !ty::type_needs_infer(*t)));
232+
231233
// Polytype of the function item (may have type params)
232234
let fn_tpt = ty::lookup_item_type(tcx, def_id);
233235

src/librustc/middle/trans/common.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -250,13 +250,25 @@ pub struct param_substs {
250250
self_ty: Option<ty::t>
251251
}
252252

253+
pub impl param_substs {
254+
fn validate(&self) {
255+
for self.tys.each |t| { fail_unless!(!ty::type_needs_infer(*t)); }
256+
for self.self_ty.each |t| { fail_unless!(!ty::type_needs_infer(*t)); }
257+
}
258+
}
259+
253260
pub fn param_substs_to_str(tcx: ty::ctxt, substs: &param_substs) -> ~str {
254261
fmt!("param_substs {tys:%?, vtables:%?, bounds:%?}",
255262
substs.tys.map(|t| ty_to_str(tcx, *t)),
256263
substs.vtables.map(|vs| vs.map(|v| v.to_str(tcx))),
257264
substs.bounds.map(|b| ty::param_bounds_to_str(tcx, *b)))
258265
}
259266

267+
pub fn opt_param_substs_to_str(tcx: ty::ctxt,
268+
substs: &Option<@param_substs>) -> ~str {
269+
substs.map_default(~"None", |&ps| param_substs_to_str(tcx, ps))
270+
}
271+
260272
// Function context. Every LLVM function we create will have one of
261273
// these.
262274
pub struct fn_ctxt_ {
@@ -1367,6 +1379,13 @@ pub fn expr_ty_adjusted(bcx: block, ex: @ast::expr) -> ty::t {
13671379
pub fn node_id_type_params(bcx: block, id: ast::node_id) -> ~[ty::t] {
13681380
let tcx = bcx.tcx();
13691381
let params = ty::node_id_to_type_params(tcx, id);
1382+
1383+
if !params.all(|t| !ty::type_needs_infer(*t)) {
1384+
bcx.sess().bug(
1385+
fmt!("Type parameters for node %d include inference types: %s",
1386+
id, str::connect(params.map(|t| bcx.ty_to_str(*t)), ",")));
1387+
}
1388+
13701389
match bcx.fcx.param_substs {
13711390
Some(substs) => {
13721391
do vec::map(params) |t| {
@@ -1423,7 +1442,7 @@ pub fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, +vt: typeck::vtable_origin)
14231442
}
14241443
14251444
pub fn find_vtable(tcx: ty::ctxt, ps: &param_substs,
1426-
n_param: uint, n_bound: uint)
1445+
n_param: uint, n_bound: uint)
14271446
-> typeck::vtable_origin {
14281447
debug!("find_vtable_in_fn_ctxt(n_param=%u, n_bound=%u, ps=%?)",
14291448
n_param, n_bound, param_substs_to_str(tcx, ps));

src/librustc/middle/trans/meth.rs

+6
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ pub fn trans_method_callee(bcx: block,
175175
-> Callee {
176176
let _icx = bcx.insn_ctxt("impl::trans_method_callee");
177177
178+
debug!("trans_method_callee(callee_id=%?, self=%s, mentry=%?)",
179+
callee_id, bcx.expr_to_str(self), mentry);
180+
178181
// Replace method_self with method_static here.
179182
let mut origin = mentry.origin;
180183
match origin {
@@ -218,6 +221,8 @@ pub fn trans_method_callee(bcx: block,
218221
typeck::method_trait(*) => {}
219222
}
220223
224+
debug!("origin=%?", origin);
225+
221226
match origin {
222227
typeck::method_static(did) => {
223228
let callee_fn = callee::trans_fn_ref(bcx, did, callee_id);
@@ -322,6 +327,7 @@ pub fn trans_static_method_callee(bcx: block,
322327
323328
match vtbls[bound_index] {
324329
typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => {
330+
fail_unless!(rcvr_substs.all(|t| !ty::type_needs_infer(*t)));
325331
326332
let mth_id = method_with_name(bcx.ccx(), impl_did, mname);
327333
let callee_substs = combine_impl_and_methods_tps(

src/librustc/middle/trans/monomorphize.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ pub fn monomorphic_fn(ccx: @CrateContext,
4747
impl_did_opt: Option<ast::def_id>,
4848
ref_id: Option<ast::node_id>) ->
4949
(ValueRef, bool) {
50+
fail_unless!(real_substs.all(|t| !ty::type_needs_infer(*t)));
5051
let _icx = ccx.insn_ctxt("monomorphic_fn");
5152
let mut must_cast = false;
5253
let substs = vec::map(real_substs, |t| {
@@ -67,9 +68,11 @@ pub fn monomorphic_fn(ccx: @CrateContext,
6768
must_cast = true;
6869
}
6970

70-
debug!("monomorphic_fn(fn_id=%? (%s), real_substs=%?, substs=%?, \
71-
hash_id = %?",
71+
debug!("monomorphic_fn(fn_id=%? (%s), vtables=%?, \
72+
real_substs=%?, substs=%?, \
73+
hash_id = %?",
7274
fn_id, ty::item_path_str(ccx.tcx, fn_id),
75+
vtables,
7376
real_substs.map(|s| ty_to_str(ccx.tcx, *s)),
7477
substs.map(|s| ty_to_str(ccx.tcx, *s)), hash_id);
7578

src/librustc/middle/typeck/astconv.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ use middle::ty::{ty_param_substs_and_ty};
6060
use middle::ty;
6161
use middle::typeck::rscope::{in_binding_rscope};
6262
use middle::typeck::rscope::{region_scope, type_rscope, RegionError};
63-
use middle::typeck::{CrateCtxt, write_substs_to_tcx, write_ty_to_tcx};
63+
use middle::typeck::{CrateCtxt};
6464

6565
use core::result;
6666
use core::vec;
@@ -186,19 +186,15 @@ pub fn ast_path_to_ty<AC:AstConv,RS:region_scope + Copy + Durable>(
186186
self: &AC,
187187
rscope: &RS,
188188
did: ast::def_id,
189-
path: @ast::path,
190-
path_id: ast::node_id)
191-
-> ty_param_substs_and_ty {
189+
path: @ast::path)
190+
-> ty_param_substs_and_ty
191+
{
192192
// Look up the polytype of the item and then substitute the provided types
193193
// for any type/region parameters.
194-
let tcx = self.tcx();
195194
let ty::ty_param_substs_and_ty {
196195
substs: substs,
197196
ty: ty
198197
} = ast_path_to_substs_and_ty(self, rscope, did, path);
199-
write_ty_to_tcx(tcx, path_id, ty);
200-
write_substs_to_tcx(tcx, path_id, /*bad*/copy substs.tps);
201-
202198
ty_param_substs_and_ty { substs: substs, ty: ty }
203199
}
204200

@@ -368,7 +364,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + Durable>(
368364
};
369365
match a_def {
370366
ast::def_ty(did) | ast::def_struct(did) => {
371-
ast_path_to_ty(self, rscope, did, path, id).ty
367+
ast_path_to_ty(self, rscope, did, path).ty
372368
}
373369
ast::def_prim_ty(nty) => {
374370
match nty {

src/librustc/middle/typeck/check/mod.rs

+32-45
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ use middle::typeck::rscope::{RegionError};
104104
use middle::typeck::rscope::{in_binding_rscope, region_scope, type_rscope};
105105
use middle::typeck::rscope;
106106
use middle::typeck::{isr_alist, lookup_def_ccx, method_map_entry};
107+
use middle::typeck::{method_map, vtable_map};
107108
use middle::typeck::{method_origin, method_self, method_trait, no_params};
108109
use middle::typeck::{require_same_types};
109110
use util::common::{block_query, indenter, loop_query};
@@ -160,9 +161,13 @@ pub struct SelfInfo {
160161
pub struct inherited {
161162
infcx: @mut infer::InferCtxt,
162163
locals: HashMap<ast::node_id, ty::t>,
164+
165+
// Temporary tables:
163166
node_types: HashMap<ast::node_id, ty::t>,
164167
node_type_substs: HashMap<ast::node_id, ty::substs>,
165-
adjustments: HashMap<ast::node_id, @ty::AutoAdjustment>
168+
adjustments: HashMap<ast::node_id, @ty::AutoAdjustment>,
169+
method_map: method_map,
170+
vtable_map: vtable_map,
166171
}
167172

168173
pub enum FnKind {
@@ -220,7 +225,9 @@ pub fn blank_inherited(ccx: @mut CrateCtxt) -> @inherited {
220225
locals: HashMap(),
221226
node_types: oldmap::HashMap(),
222227
node_type_substs: oldmap::HashMap(),
223-
adjustments: oldmap::HashMap()
228+
adjustments: oldmap::HashMap(),
229+
method_map: oldmap::HashMap(),
230+
vtable_map: oldmap::HashMap(),
224231
}
225232
}
226233

@@ -1321,13 +1328,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
13211328
sugar: ast::CallSugar) {
13221329
// Index expressions need to be handled separately, to inform them
13231330
// that they appear in call position.
1324-
match f.node {
1325-
ast::expr_field(ref base, ref field, ref tys) => {
1326-
check_field(fcx, f, true, *base, *field, *tys)
1327-
}
1328-
_ => check_expr(fcx, f)
1329-
};
1330-
1331+
let mut bot = check_expr(fcx, f);
13311332
check_call_or_method(fcx,
13321333
sp,
13331334
call_expr_id,
@@ -1363,7 +1364,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
13631364
CheckTraitsAndInherentMethods,
13641365
AutoderefReceiver) {
13651366
Some(ref entry) => {
1366-
let method_map = fcx.ccx.method_map;
1367+
let method_map = fcx.inh.method_map;
13671368
method_map.insert(expr.id, (*entry));
13681369
}
13691370
None => {
@@ -1435,7 +1436,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
14351436
deref_args, CheckTraitsOnly, autoderef_receiver) {
14361437
Some(ref origin) => {
14371438
let method_ty = fcx.node_ty(op_ex.callee_id);
1438-
let method_map = fcx.ccx.method_map;
1439+
let method_map = fcx.inh.method_map;
14391440
method_map.insert(op_ex.id, *origin);
14401441
check_call_inner(fcx, op_ex.span,
14411442
op_ex.id, method_ty,
@@ -1689,7 +1690,6 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
16891690
// Check field access expressions
16901691
fn check_field(fcx: @mut FnCtxt,
16911692
expr: @ast::expr,
1692-
is_callee: bool,
16931693
base: @ast::expr,
16941694
field: ast::ident,
16951695
tys: &[@ast::Ty]) {
@@ -1723,7 +1723,6 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
17231723
}
17241724

17251725
let tps = vec::map(tys, |ty| fcx.to_ty(*ty));
1726-
17271726
match method::lookup(fcx,
17281727
expr,
17291728
base,
@@ -1734,34 +1733,30 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
17341733
DontDerefArgs,
17351734
CheckTraitsAndInherentMethods,
17361735
AutoderefReceiver) {
1737-
Some(ref entry) => {
1738-
let method_map = fcx.ccx.method_map;
1739-
method_map.insert(expr.id, (*entry));
1740-
1741-
// If we have resolved to a method but this is not in
1742-
// a callee position, error
1743-
if !is_callee {
1744-
tcx.sess.span_err(
1745-
expr.span,
1746-
~"attempted to take value of method \
1747-
(try writing an anonymous function)");
1748-
// Add error type for the result
1749-
fcx.write_error(expr.id);
1750-
}
1736+
Some(_) => {
1737+
fcx.type_error_message(
1738+
expr.span,
1739+
|actual| {
1740+
fmt!("attempted to take value of method `%s` on type `%s` \
1741+
(try writing an anonymous function)",
1742+
*tcx.sess.str_of(field), actual)
1743+
},
1744+
expr_t, None);
17511745
}
1746+
17521747
None => {
1753-
fcx.type_error_message(expr.span,
1754-
|actual| {
1755-
fmt!("attempted access of field `%s` on type `%s`, but \
1756-
no field or method with that name was found",
1757-
*tcx.sess.str_of(field), actual)
1758-
},
1759-
expr_t, None);
1760-
// Add error type for the result
1761-
fcx.write_error(expr.id);
1748+
fcx.type_error_message(
1749+
expr.span,
1750+
|actual| {
1751+
fmt!("attempted access of field `%s` on type `%s`, \
1752+
but no field with that name was found",
1753+
*tcx.sess.str_of(field), actual)
1754+
},
1755+
expr_t, None);
17621756
}
17631757
}
17641758

1759+
fcx.write_error(expr.id);
17651760
}
17661761

17671762
fn check_struct_or_variant_fields(fcx: @mut FnCtxt,
@@ -2750,15 +2745,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
27502745
}
27512746
}
27522747
ast::expr_field(base, field, ref tys) => {
2753-
check_field(fcx, expr, false, base, field, * tys);
2754-
let base_t = fcx.expr_ty(base);
2755-
if ty::type_is_error(base_t) {
2756-
fcx.write_error(id);
2757-
}
2758-
else if ty::type_is_bot(base_t) {
2759-
fcx.write_bot(id);
2760-
}
2761-
// Otherwise, type already got written
2748+
check_field(fcx, expr, base, field, *tys);
27622749
}
27632750
ast::expr_index(base, idx) => {
27642751
check_expr(fcx, base);

src/librustc/middle/typeck/check/regionck.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ pub fn visit_expr(expr: @ast::expr, &&rcx: @mut Rcx, v: rvt) {
215215
// `constrain_auto_ref()` on all exprs. But that causes a
216216
// lot of spurious errors because of how the region
217217
// hierarchy is setup.
218-
if rcx.fcx.ccx.method_map.contains_key(&callee.id) {
218+
if rcx.fcx.inh.method_map.contains_key(&callee.id) {
219219
match callee.node {
220220
ast::expr_field(base, _, _) => {
221221
constrain_auto_ref(rcx, base);
@@ -713,7 +713,7 @@ pub mod guarantor {
713713
ast::expr_repeat(*) |
714714
ast::expr_vec(*) => {
715715
fail_unless!(!ty::expr_is_lval(
716-
rcx.fcx.tcx(), rcx.fcx.ccx.method_map, expr));
716+
rcx.fcx.tcx(), rcx.fcx.inh.method_map, expr));
717717
None
718718
}
719719
}
@@ -765,7 +765,7 @@ pub mod guarantor {
765765
let _i = ::util::common::indenter();
766766

767767
let guarantor = {
768-
if rcx.fcx.ccx.method_map.contains_key(&expr.id) {
768+
if rcx.fcx.inh.method_map.contains_key(&expr.id) {
769769
None
770770
} else {
771771
guarantor(rcx, expr)

0 commit comments

Comments
 (0)