Emit a better error message for unbound type parameters in nested functions

This code was causing a bounds check failure:

fn hd[U](&vec[U] v) -> U {
  fn hd1(&vec[U] w) -> U {
    ret w.(0);
  }
  ret hd1(v);
}

because in hd1, U was being treated as if it referred to a type
parameter of hd1, rather than referring to the lexically enclosing binding
for U that's part of hd.

I'm actually not sure whether this is a legit program or not. But I wanted
to get rid of the bounds check error, so I assumed that program shouldn't
compile and made it a proper error message.
This commit is contained in:
Tim Chevalier 2011-06-21 17:56:56 -07:00
parent efd8ff4647
commit 1a6d029b07
3 changed files with 23 additions and 7 deletions

View File

@ -2580,18 +2580,23 @@ fn type_err_to_str(&ty::type_err err) -> str {
// Converts type parameters in a type to type variables and returns the
// resulting type along with a list of type variable IDs.
fn bind_params_in_type(&ctxt cx, fn() -> int next_ty_var, t typ,
fn bind_params_in_type(&span sp, &ctxt cx, fn() -> int next_ty_var, t typ,
uint ty_param_count) -> tup(vec[int], t) {
let vec[int] param_var_ids = [];
auto i = 0u;
while (i < ty_param_count) { param_var_ids += [next_ty_var()]; i += 1u; }
fn binder(ctxt cx, vec[int] param_var_ids, fn() -> int next_ty_var,
uint index) -> t {
ret mk_var(cx, param_var_ids.(index));
fn binder(span sp, ctxt cx, vec[int] param_var_ids,
fn() -> int next_ty_var, uint index) -> t {
if (index < vec::len(param_var_ids)) {
ret mk_var(cx, param_var_ids.(index));
}
else {
cx.sess.span_fatal(sp, "Unbound type parameter in callee's type");
}
}
auto new_typ =
fold_ty(cx, fm_param(bind binder(cx, param_var_ids, next_ty_var, _)),
typ);
fold_ty(cx, fm_param(bind binder(sp, cx, param_var_ids,
next_ty_var, _)), typ);
ret tup(param_var_ids, new_typ);
}

View File

@ -132,7 +132,7 @@ fn instantiate_path(&@fn_ctxt fcx, &ast::path pth, &ty_param_count_and_ty tpt,
&span sp) -> ty_param_substs_opt_and_ty {
auto ty_param_count = tpt._0;
auto bind_result =
bind_params_in_type(fcx.ccx.tcx, bind next_ty_var_id(fcx), tpt._1,
bind_params_in_type(sp, fcx.ccx.tcx, bind next_ty_var_id(fcx), tpt._1,
ty_param_count);
auto ty_param_vars = bind_result._0;
auto t = bind_result._1;

View File

@ -0,0 +1,11 @@
// error-pattern:Unbound type parameter in callee
/* I'm actually not sure whether this should compile.
But having a nice error message seems better than
a bounds check failure (which is what was happening
before.) */
fn hd[U](&vec[U] v) -> U {
fn hd1(&vec[U] w) -> U {
ret w.(0);
}
ret hd1(v);
}