diff options
| author | Paul Stansifer <paul.stansifer@gmail.com> | 2011-06-02 14:03:17 -0700 |
|---|---|---|
| committer | Paul Stansifer <paul.stansifer@gmail.com> | 2011-06-02 14:03:17 -0700 |
| commit | 5cd10d2fef8ffa68903b18726f19ac52a04725cc (patch) | |
| tree | 67a1fdbd048b6297a38ad645e37d61e00bb19eb0 /src/comp/middle | |
| parent | 1b67fbdfd30ef55510ef57e68f106a72cd19b7be (diff) | |
| download | rust-5cd10d2fef8ffa68903b18726f19ac52a04725cc.tar.gz rust-5cd10d2fef8ffa68903b18726f19ac52a04725cc.zip | |
Error message, instead of segfault, when recursive types are used.
Diffstat (limited to 'src/comp/middle')
| -rw-r--r-- | src/comp/middle/ty.rs | 12 | ||||
| -rw-r--r-- | src/comp/middle/typeck.rs | 14 |
2 files changed, 23 insertions, 3 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index f936d7513e5..70557a97ed4 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -61,6 +61,11 @@ type item_table = hashmap[ast::def_id,any_item]; type mt = rec(t ty, ast::mutability mut); +tag cached_ty { + in_progress; + done(t); +} + // Contains information needed to resolve types and (in the future) look up // the types of AST nodes. type creader_cache = hashmap[tup(int,uint,uint),ty::t]; @@ -71,7 +76,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,cached_ty] 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 @@ -245,7 +251,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,cached_ty](ast::hash_ty, ast::eq_ty)); populate_type_store(cx); ret cx; diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 6b69dba49ae..690ecd4aba8 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -227,6 +227,16 @@ fn ast_mode_to_mode(ast::mode mode) -> ty::mode { // 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[ty::cached_ty](ty::done(?ty))) { ret ty; } + case (some[ty::cached_ty](ty::in_progress)) { + tcx.sess.span_err(ast_ty.span, "illegal recursive type " + + "(insert a tag in the cycle, if this is desired)"); + } + case (none[ty::cached_ty]) { } /* go on */ + } + tcx.ast_ty_to_ty_cache.insert(ast_ty, ty::in_progress); + fn ast_arg_to_arg(&ty::ctxt tcx, &ty_getter getter, &rec(ast::mode mode, @ast::ty ty) arg) @@ -329,7 +339,7 @@ fn ast_ty_to_ty(&ty::ctxt tcx, &ty_getter getter, &@ast::ty ast_ty) -> ty::t { case (_) { tcx.sess.span_err(ast_ty.span, "found type name used as a variable"); - fail; } + } } cname = some(path_to_str(path)); @@ -360,6 +370,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, ty::done(typ)); ret typ; } |
