Skip to content

Commit

Permalink
Merge pull request #447 from paulstansifer/quick_error_message_fix
Browse files Browse the repository at this point in the history
Error message, instead of segfault, when recursive types are used.
  • Loading branch information
pcwalton committed Jun 10, 2011
2 parents dfdd6db + 1377e9b commit 7b7c746
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 2 deletions.
8 changes: 8 additions & 0 deletions src/comp/front/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,14 @@ fn is_constraint_arg(@expr e) -> bool {
}
}

fn eq_ty(&@ty a, &@ty b) -> bool {
ret std::box::ptr_eq(a,b);
}

fn hash_ty(&@ty t) -> uint {
ret t.span.lo << 16u + t.span.hi;
}

//
// Local Variables:
// mode: rust
Expand Down
7 changes: 5 additions & 2 deletions src/comp/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ type ctxt = rec(@type_store ts,
item_table items,
type_cache tcache,
creader_cache rcache,
hashmap[t,str] short_names_cache);
hashmap[t,str] short_names_cache,
hashmap[@ast::ty,option::t[t]] ast_ty_to_ty_cache);
type ty_ctxt = ctxt; // Needed for disambiguation from unify::ctxt.

// Convert from method type to function type. Pretty easy; we just drop
Expand Down Expand Up @@ -241,7 +242,9 @@ fn mk_ctxt(session::session s, resolve::def_map dm) -> ctxt {
tcache = tcache,
rcache = mk_rcache(),
short_names_cache =
map::mk_hashmap[ty::t,str](ty::hash_ty, ty::eq_ty));
map::mk_hashmap[ty::t,str](ty::hash_ty, ty::eq_ty),
ast_ty_to_ty_cache =
map::mk_hashmap[@ast::ty,option::t[t]](ast::hash_ty, ast::eq_ty));

populate_type_store(cx);
ret cx;
Expand Down
12 changes: 12 additions & 0 deletions src/comp/middle/typeck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,16 @@ fn type_is_scalar(&@fn_ctxt fcx, &span sp, ty::t typ) -> bool {
// notion of a type. `getter` is a function that returns the type
// corresponding to a definition ID:
fn ast_ty_to_ty(&ty::ctxt tcx, &ty_getter getter, &@ast::ty ast_ty) -> ty::t {
alt (tcx.ast_ty_to_ty_cache.find(ast_ty)) {
case (some[option::t[ty::t]](some[ty::t](?ty))) { ret ty; }
case (some[option::t[ty::t]](none)) {
tcx.sess.span_err(ast_ty.span, "illegal recursive type "
+ "(insert a tag in the cycle, if this is desired)");
}
case (none[option::t[ty::t]]) { } /* go on */
}
tcx.ast_ty_to_ty_cache.insert(ast_ty, none[ty::t]);

fn ast_arg_to_arg(&ty::ctxt tcx,
&ty_getter getter,
&ast::ty_arg arg)
Expand Down Expand Up @@ -369,6 +379,8 @@ fn ast_ty_to_ty(&ty::ctxt tcx, &ty_getter getter, &@ast::ty ast_ty) -> ty::t {
typ = ty::rename(tcx, typ, cname_str);
}
}

tcx.ast_ty_to_ty_cache.insert(ast_ty, some(typ));
ret typ;
}

Expand Down
4 changes: 4 additions & 0 deletions src/test/compile-fail/type-recursive.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// error-pattern:illegal recursive type
type t1 = rec(int foo, t1 foolish);

fn main() {}

0 comments on commit 7b7c746

Please sign in to comment.