mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Error message, instead of segfault, when recursive types are used.
This commit is contained in:
parent
1b67fbdfd3
commit
5cd10d2fef
@ -503,6 +503,14 @@ fn is_constraint_arg(@expr e) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn eq_ty(&@ty a, &@ty b) -> bool {
|
||||
ret a == b;
|
||||
}
|
||||
|
||||
fn hash_ty(&@ty t) -> uint {
|
||||
ret t.span.lo << 16u + t.span.hi;
|
||||
}
|
||||
|
||||
//
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
4
src/test/compile-fail/type-recursive.rs
Normal file
4
src/test/compile-fail/type-recursive.rs
Normal file
@ -0,0 +1,4 @@
|
||||
// error-pattern:illegal recursive type
|
||||
type t1 = rec(int foo, t1 foolish);
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user