about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-06-10 10:53:42 -0700
committerPatrick Walton <pcwalton@mimiga.net>2011-06-10 10:53:42 -0700
commit7b7c746c1e92fe9fa50a94396dfe5efae0034df9 (patch)
treefce25e8fd6ae9fb6c381724e75cc59c4fc16f585 /src/comp
parentdfdd6dbc5464147d984470086ab27c950d60d83e (diff)
parent1377e9b341a03915c48a564fb30e70022d04c78f (diff)
downloadrust-7b7c746c1e92fe9fa50a94396dfe5efae0034df9.tar.gz
rust-7b7c746c1e92fe9fa50a94396dfe5efae0034df9.zip
Merge pull request #447 from paulstansifer/quick_error_message_fix
Error message, instead of segfault, when recursive types are used.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/ast.rs8
-rw-r--r--src/comp/middle/ty.rs7
-rw-r--r--src/comp/middle/typeck.rs12
3 files changed, 25 insertions, 2 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index a61562b9c16..d30af2a6d13 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -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
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 79ac28b1590..61053f77091 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -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
@@ -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;
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 289691444b0..cf99f1ab4b1 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -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)
@@ -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;
 }