From cf69604551324f68d1fc7ab0386ecbe9e1aaa504 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Mon, 25 Jun 2012 22:10:28 -0700 Subject: [PATCH] Incorporate class fields into recursive-type check Noticed while investigating issue 2718 that the typechecker allowed some non-instantiable types involving classes. This wasn't the root of 2718, but fixed it anyway. --- src/rustc/middle/ty.rs | 10 +++++++++- src/test/compile-fail/issue-2718-a.rs | 12 ++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/issue-2718-a.rs diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index fa93925fa88f..3a9d320c77e0 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -1218,7 +1218,6 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool { accum } } - ty_tup(elts) { for elts.each {|m| if type_needs_drop(cx, m) { accum = true; } } accum @@ -1720,6 +1719,7 @@ fn is_instantiable(cx: ctxt, r_ty: t) -> bool { fn type_structurally_contains(cx: ctxt, ty: t, test: fn(sty) -> bool) -> bool { let sty = get(ty).struct; + #debug("type_structurally_contains: %s", ty_to_str(cx, ty)); if test(sty) { ret true; } alt sty { ty_enum(did, substs) { @@ -1737,6 +1737,14 @@ fn type_structurally_contains(cx: ctxt, ty: t, test: fn(sty) -> bool) -> } ret false; } + ty_class(did, substs) { + for lookup_class_fields(cx, did).each {|field| + let ft = lookup_field_type(cx, did, field.id, substs); + if type_structurally_contains(cx, ft, test) { ret true; } + } + ret false; + } + ty_tup(ts) { for ts.each {|tt| if type_structurally_contains(cx, tt, test) { ret true; } diff --git a/src/test/compile-fail/issue-2718-a.rs b/src/test/compile-fail/issue-2718-a.rs new file mode 100644 index 000000000000..1eb8d4a1b695 --- /dev/null +++ b/src/test/compile-fail/issue-2718-a.rs @@ -0,0 +1,12 @@ +class send_packet { + let p: T; + new(p: T) { self.p = p; } +} + + +mod pingpong { + type ping = send_packet; + enum pong = send_packet; //! ERROR illegal recursive enum type; wrap the inner value in a box to make it representable +} + +fn main() {}