Skip to content

Commit 84adcb9

Browse files
committed
Rework lint to copy lint mode maps when changing them.
1 parent 7b02f29 commit 84adcb9

File tree

1 file changed

+30
-16
lines changed

1 file changed

+30
-16
lines changed

src/rustc/middle/lint.rs

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,25 @@ fn get_lint_dict() -> lint_dict {
8787
hash_from_strs(v)
8888
}
8989

90-
type ctxt = @{dict: lint_dict,
91-
curr: smallintmap<level>,
92-
tcx: ty::ctxt};
90+
// This is a highly not-optimal set of data structure decisions.
91+
type lint_modes = smallintmap<level>;
92+
type lint_mode_map = hashmap<ast::node_id, lint_modes>;
93+
94+
type warning_settings = {
95+
default_settings: lint_modes,
96+
settings_map: lint_mode_map
97+
};
98+
99+
// This is kind of unfortunate. It should be somewhere else, or we should use
100+
// a persistent data structure...
101+
fn clone_lint_modes(modes: lint_modes) -> lint_modes {
102+
@{v: copy modes.v}
103+
}
104+
105+
type ctxt = {dict: lint_dict,
106+
curr: lint_modes,
107+
tcx: ty::ctxt};
108+
93109

94110
impl methods for ctxt {
95111
fn get_level(lint: lint) -> level {
@@ -122,7 +138,7 @@ impl methods for ctxt {
122138
"]
123139
fn with_warn_attrs(attrs: [ast::attribute], f: fn(ctxt)) {
124140

125-
let mut undo = [];
141+
let mut new_ctxt = self;
126142

127143
let metas = attr::attr_metas(attr::find_attrs_by_name(attrs, "warn"));
128144
for metas.each {|meta|
@@ -138,9 +154,12 @@ impl methods for ctxt {
138154
#fmt("unknown warning: '%s'", lintname));
139155
}
140156
some((lint, new_level)) {
141-
let old_level = self.get_level(lint);
142-
self.set_level(lint, new_level);
143-
undo += [(lint, old_level)]
157+
// we do multiple unneeded copies of the map
158+
// if many attributes are set, but this shouldn't
159+
// actually be a problem...
160+
new_ctxt = {curr: clone_lint_modes(self.curr)
161+
with new_ctxt};
162+
new_ctxt.set_level(lint, new_level);
144163
}
145164
}
146165
}
@@ -159,12 +178,7 @@ impl methods for ctxt {
159178
}
160179
}
161180

162-
f(self);
163-
164-
for undo.each {|pair|
165-
let (lint,old_level) = pair;
166-
self.set_level(lint, old_level);
167-
}
181+
f(new_ctxt);
168182
}
169183
}
170184

@@ -350,9 +364,9 @@ fn check_crate(tcx: ty::ctxt, crate: @ast::crate,
350364
fn hash_lint(&&lint: lint) -> uint { lint as uint }
351365
fn eq_lint(&&a: lint, &&b: lint) -> bool { a == b }
352366

353-
let cx = @{dict: get_lint_dict(),
354-
curr: std::smallintmap::mk(),
355-
tcx: tcx};
367+
let cx = {dict: get_lint_dict(),
368+
curr: std::smallintmap::mk(),
369+
tcx: tcx};
356370

357371
// Install defaults.
358372
for cx.dict.each {|_k, spec| cx.set_level(spec.lint, spec.default); }

0 commit comments

Comments
 (0)