Skip to content

Commit ecb6464

Browse files
committed
Add lint modes for uses of @ and ~ pointers, in general.
1 parent b769e29 commit ecb6464

File tree

4 files changed

+119
-1
lines changed

4 files changed

+119
-1
lines changed

src/rustc/middle/lint.rs

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import driver::session;
22
import driver::session::session;
33
import middle::ty;
4-
import syntax::{ast, visit};
4+
import syntax::{ast, ast_util, visit};
55
import syntax::attr;
66
import syntax::codemap::span;
77
import std::map::{map,hashmap,int_hash,hash_from_strs};
@@ -54,6 +54,10 @@ enum lint {
5454
deprecated_pattern,
5555
non_camel_case_types,
5656

57+
managed_heap_memory,
58+
owned_heap_memory,
59+
heap_memory,
60+
5761
// FIXME(#3266)--make liveness warnings lintable
5862
// unused_variable,
5963
// dead_assignment
@@ -140,6 +144,21 @@ fn get_lint_dict() -> lint_dict {
140144
desc: ~"types, variants and traits must have camel case names",
141145
default: allow}),
142146

147+
(~"managed_heap_memory",
148+
@{lint: managed_heap_memory,
149+
desc: ~"use of managed (@ type) heap memory",
150+
default: allow}),
151+
152+
(~"owned_heap_memory",
153+
@{lint: owned_heap_memory,
154+
desc: ~"use of owned (~ type) heap memory",
155+
default: allow}),
156+
157+
(~"heap_memory",
158+
@{lint: heap_memory,
159+
desc: ~"use of any (~ type or @ type) heap memory",
160+
default: allow}),
161+
143162
/* FIXME(#3266)--make liveness warnings lintable
144163
(~"unused_variable",
145164
@{lint: unused_variable,
@@ -348,6 +367,7 @@ fn check_item(i: @ast::item, cx: ty::ctxt) {
348367
check_item_while_true(cx, i);
349368
check_item_path_statement(cx, i);
350369
check_item_non_camel_case_types(cx, i);
370+
check_item_heap(cx, i);
351371
}
352372

353373
// 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) {
428448
}
429449
}
430450

451+
fn check_item_heap(cx: ty::ctxt, it: @ast::item) {
452+
453+
fn check_type_for_lint(cx: ty::ctxt, lint: lint,
454+
node: ast::node_id,
455+
item: ast::node_id,
456+
span: span, ty: ty::t) {
457+
458+
if get_lint_settings_level(cx.sess.lint_settings,
459+
lint, node, item) != allow {
460+
let mut n_box = 0;
461+
let mut n_uniq = 0;
462+
ty::fold_ty(cx, ty, |t| {
463+
match ty::get(t).struct {
464+
ty::ty_box(_) => n_box += 1,
465+
ty::ty_uniq(_) => n_uniq += 1,
466+
_ => ()
467+
};
468+
t
469+
});
470+
471+
if (n_uniq > 0 && lint != managed_heap_memory) {
472+
let s = ty_to_str(cx, ty);
473+
let m = ~"type uses owned (~ type) pointers: " + s;
474+
cx.sess.span_lint(lint, node, item, span, m);
475+
}
476+
477+
if (n_box > 0 && lint != owned_heap_memory) {
478+
let s = ty_to_str(cx, ty);
479+
let m = ~"type uses managed (@ type) pointers: " + s;
480+
cx.sess.span_lint(lint, node, item, span, m);
481+
}
482+
}
483+
}
484+
485+
fn check_type(cx: ty::ctxt,
486+
node: ast::node_id,
487+
item: ast::node_id,
488+
span: span, ty: ty::t) {
489+
for [managed_heap_memory,
490+
owned_heap_memory,
491+
heap_memory].each |lint| {
492+
check_type_for_lint(cx, lint, node, item, span, ty);
493+
}
494+
}
495+
496+
match it.node {
497+
ast::item_fn(*) |
498+
ast::item_ty(*) |
499+
ast::item_enum(*) |
500+
ast::item_class(*) |
501+
ast::item_trait(*) => check_type(cx, it.id, it.id, it.span,
502+
ty::node_id_to_type(cx, it.id)),
503+
_ => ()
504+
}
505+
506+
let visit = item_stopping_visitor(visit::mk_simple_visitor(@{
507+
visit_expr: fn@(e: @ast::expr) {
508+
let ty = ty::expr_ty(cx, e);
509+
check_type(cx, e.id, it.id, e.span, ty);
510+
}
511+
with *visit::default_simple_visitor()
512+
}));
513+
visit::visit_item(it, (), visit);
514+
}
515+
431516
fn check_item_path_statement(cx: ty::ctxt, it: @ast::item) {
432517
let visit = item_stopping_visitor(visit::mk_simple_visitor(@{
433518
visit_stmt: fn@(s: @ast::stmt) {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#[forbid(heap_memory)];
2+
3+
type foo = { //~ ERROR type uses managed
4+
x: @int
5+
};
6+
7+
fn main() {
8+
let _x : { x : ~int } = {x : ~10};
9+
//~^ ERROR type uses owned
10+
//~^^ ERROR type uses owned
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#[forbid(managed_heap_memory)];
2+
3+
type foo = { //~ ERROR type uses managed
4+
x: @int
5+
};
6+
7+
fn main() {
8+
let _x : foo = {x : @10};
9+
//~^ ERROR type uses managed
10+
//~^^ ERROR type uses managed
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#[forbid(owned_heap_memory)];
2+
3+
type foo = { //~ ERROR type uses owned
4+
x: ~int
5+
};
6+
7+
fn main() {
8+
let _x : foo = {x : ~10};
9+
//~^ ERROR type uses owned
10+
//~^^ ERROR type uses owned
11+
}

0 commit comments

Comments
 (0)