Skip to content

Commit 7b7c746

Browse files
committed
Merge pull request #447 from paulstansifer/quick_error_message_fix
Error message, instead of segfault, when recursive types are used.
2 parents dfdd6db + 1377e9b commit 7b7c746

File tree

4 files changed

+29
-2
lines changed

4 files changed

+29
-2
lines changed

src/comp/front/ast.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,14 @@ fn is_constraint_arg(@expr e) -> bool {
525525
}
526526
}
527527

528+
fn eq_ty(&@ty a, &@ty b) -> bool {
529+
ret std::box::ptr_eq(a,b);
530+
}
531+
532+
fn hash_ty(&@ty t) -> uint {
533+
ret t.span.lo << 16u + t.span.hi;
534+
}
535+
528536
//
529537
// Local Variables:
530538
// mode: rust

src/comp/middle/ty.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ type ctxt = rec(@type_store ts,
7272
item_table items,
7373
type_cache tcache,
7474
creader_cache rcache,
75-
hashmap[t,str] short_names_cache);
75+
hashmap[t,str] short_names_cache,
76+
hashmap[@ast::ty,option::t[t]] ast_ty_to_ty_cache);
7677
type ty_ctxt = ctxt; // Needed for disambiguation from unify::ctxt.
7778

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

246249
populate_type_store(cx);
247250
ret cx;

src/comp/middle/typeck.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,16 @@ fn type_is_scalar(&@fn_ctxt fcx, &span sp, ty::t typ) -> bool {
219219
// notion of a type. `getter` is a function that returns the type
220220
// corresponding to a definition ID:
221221
fn ast_ty_to_ty(&ty::ctxt tcx, &ty_getter getter, &@ast::ty ast_ty) -> ty::t {
222+
alt (tcx.ast_ty_to_ty_cache.find(ast_ty)) {
223+
case (some[option::t[ty::t]](some[ty::t](?ty))) { ret ty; }
224+
case (some[option::t[ty::t]](none)) {
225+
tcx.sess.span_err(ast_ty.span, "illegal recursive type "
226+
+ "(insert a tag in the cycle, if this is desired)");
227+
}
228+
case (none[option::t[ty::t]]) { } /* go on */
229+
}
230+
tcx.ast_ty_to_ty_cache.insert(ast_ty, none[ty::t]);
231+
222232
fn ast_arg_to_arg(&ty::ctxt tcx,
223233
&ty_getter getter,
224234
&ast::ty_arg arg)
@@ -369,6 +379,8 @@ fn ast_ty_to_ty(&ty::ctxt tcx, &ty_getter getter, &@ast::ty ast_ty) -> ty::t {
369379
typ = ty::rename(tcx, typ, cname_str);
370380
}
371381
}
382+
383+
tcx.ast_ty_to_ty_cache.insert(ast_ty, some(typ));
372384
ret typ;
373385
}
374386

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// error-pattern:illegal recursive type
2+
type t1 = rec(int foo, t1 foolish);
3+
4+
fn main() {}

0 commit comments

Comments
 (0)