about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/rustc/middle/lint.rs87
-rw-r--r--src/test/compile-fail/lint-heap-memory.rs11
-rw-r--r--src/test/compile-fail/lint-managed-heap-memory.rs11
-rw-r--r--src/test/compile-fail/lint-owned-heap-memory.rs11
4 files changed, 119 insertions, 1 deletions
diff --git a/src/rustc/middle/lint.rs b/src/rustc/middle/lint.rs
index f5565de7d94..ed7ac7e85ce 100644
--- a/src/rustc/middle/lint.rs
+++ b/src/rustc/middle/lint.rs
@@ -1,7 +1,7 @@
 import driver::session;
 import driver::session::session;
 import middle::ty;
-import syntax::{ast, visit};
+import syntax::{ast, ast_util, visit};
 import syntax::attr;
 import syntax::codemap::span;
 import std::map::{map,hashmap,int_hash,hash_from_strs};
@@ -54,6 +54,10 @@ enum lint {
     deprecated_pattern,
     non_camel_case_types,
 
+    managed_heap_memory,
+    owned_heap_memory,
+    heap_memory,
+
     // FIXME(#3266)--make liveness warnings lintable
     // unused_variable,
     // dead_assignment
@@ -140,6 +144,21 @@ fn get_lint_dict() -> lint_dict {
            desc: ~"types, variants and traits must have camel case names",
            default: allow}),
 
+        (~"managed_heap_memory",
+         @{lint: managed_heap_memory,
+           desc: ~"use of managed (@ type) heap memory",
+           default: allow}),
+
+        (~"owned_heap_memory",
+         @{lint: owned_heap_memory,
+           desc: ~"use of owned (~ type) heap memory",
+           default: allow}),
+
+        (~"heap_memory",
+         @{lint: heap_memory,
+           desc: ~"use of any (~ type or @ type) heap memory",
+           default: allow}),
+
         /* FIXME(#3266)--make liveness warnings lintable
         (~"unused_variable",
          @{lint: unused_variable,
@@ -348,6 +367,7 @@ fn check_item(i: @ast::item, cx: ty::ctxt) {
     check_item_while_true(cx, i);
     check_item_path_statement(cx, i);
     check_item_non_camel_case_types(cx, i);
+    check_item_heap(cx, i);
 }
 
 // Take a visitor, and modify it so that it will not proceed past subitems.
@@ -428,6 +448,71 @@ fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) {
     }
 }
 
+fn check_item_heap(cx: ty::ctxt, it: @ast::item) {
+
+    fn check_type_for_lint(cx: ty::ctxt, lint: lint,
+                           node: ast::node_id,
+                           item: ast::node_id,
+                           span: span, ty: ty::t) {
+
+        if get_lint_settings_level(cx.sess.lint_settings,
+                                   lint, node, item) != allow {
+            let mut n_box = 0;
+            let mut n_uniq = 0;
+            ty::fold_ty(cx, ty, |t| {
+                match ty::get(t).struct {
+                  ty::ty_box(_) => n_box += 1,
+                  ty::ty_uniq(_) => n_uniq += 1,
+                  _ => ()
+                };
+                t
+            });
+
+            if (n_uniq > 0 && lint != managed_heap_memory) {
+                let s = ty_to_str(cx, ty);
+                let m = ~"type uses owned (~ type) pointers: " + s;
+                cx.sess.span_lint(lint, node, item, span, m);
+            }
+
+            if (n_box > 0 && lint != owned_heap_memory) {
+                let s = ty_to_str(cx, ty);
+                let m = ~"type uses managed (@ type) pointers: " + s;
+                cx.sess.span_lint(lint, node, item, span, m);
+            }
+        }
+    }
+
+    fn check_type(cx: ty::ctxt,
+                  node: ast::node_id,
+                  item: ast::node_id,
+                  span: span, ty: ty::t) {
+            for [managed_heap_memory,
+                 owned_heap_memory,
+                 heap_memory].each |lint| {
+                check_type_for_lint(cx, lint, node, item, span, ty);
+            }
+    }
+
+    match it.node {
+      ast::item_fn(*) |
+      ast::item_ty(*) |
+      ast::item_enum(*) |
+      ast::item_class(*) |
+      ast::item_trait(*) => check_type(cx, it.id, it.id, it.span,
+                                       ty::node_id_to_type(cx, it.id)),
+      _ => ()
+    }
+
+    let visit = item_stopping_visitor(visit::mk_simple_visitor(@{
+        visit_expr: fn@(e: @ast::expr) {
+            let ty = ty::expr_ty(cx, e);
+            check_type(cx, e.id, it.id, e.span, ty);
+        }
+        with *visit::default_simple_visitor()
+    }));
+    visit::visit_item(it, (), visit);
+}
+
 fn check_item_path_statement(cx: ty::ctxt, it: @ast::item) {
     let visit = item_stopping_visitor(visit::mk_simple_visitor(@{
         visit_stmt: fn@(s: @ast::stmt) {
diff --git a/src/test/compile-fail/lint-heap-memory.rs b/src/test/compile-fail/lint-heap-memory.rs
new file mode 100644
index 00000000000..cc29e75d64a
--- /dev/null
+++ b/src/test/compile-fail/lint-heap-memory.rs
@@ -0,0 +1,11 @@
+#[forbid(heap_memory)];
+
+type foo = { //~ ERROR type uses managed
+    x: @int
+};
+
+fn main() {
+    let _x : { x : ~int } = {x : ~10};
+    //~^ ERROR type uses owned
+    //~^^ ERROR type uses owned
+}
diff --git a/src/test/compile-fail/lint-managed-heap-memory.rs b/src/test/compile-fail/lint-managed-heap-memory.rs
new file mode 100644
index 00000000000..bfefc476e63
--- /dev/null
+++ b/src/test/compile-fail/lint-managed-heap-memory.rs
@@ -0,0 +1,11 @@
+#[forbid(managed_heap_memory)];
+
+type foo = { //~ ERROR type uses managed
+    x: @int
+};
+
+fn main() {
+    let _x : foo = {x : @10};
+    //~^ ERROR type uses managed
+    //~^^ ERROR type uses managed
+}
diff --git a/src/test/compile-fail/lint-owned-heap-memory.rs b/src/test/compile-fail/lint-owned-heap-memory.rs
new file mode 100644
index 00000000000..7c00a3f18b3
--- /dev/null
+++ b/src/test/compile-fail/lint-owned-heap-memory.rs
@@ -0,0 +1,11 @@
+#[forbid(owned_heap_memory)];
+
+type foo = { //~ ERROR type uses owned
+    x: ~int
+};
+
+fn main() {
+    let _x : foo = {x : ~10};
+    //~^ ERROR type uses owned
+    //~^^ ERROR type uses owned
+}