Skip to content

Commit b250d9a

Browse files
committed
rollup merge of rust-lang#21289: brson/errorcodes
This does the bare minimum to make registration of error codes work again. After this patch, every call to `span_err!` with an error code gets that error code validated against a list in that crate and a new tidy script `errorck.py` validates that no error codes are duplicated globally. There are further improvements to be made yet, detailed in rust-lang#19624. r? @nikomatsakis
2 parents 41890bf + 876b266 commit b250d9a

38 files changed

+618
-476
lines changed

mk/tests.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ tidy:
300300
| grep '^$(S)src/libbacktrace' -v \
301301
| grep '^$(S)src/rust-installer' -v \
302302
| xargs $(CFG_PYTHON) $(S)src/etc/check-binaries.py
303+
$(Q) $(CFG_PYTHON) $(S)src/etc/errorck.py $(S)src/
303304

304305

305306
endif

src/etc/errorck.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
# file at the top-level directory of this distribution and at
3+
# http://rust-lang.org/COPYRIGHT.
4+
#
5+
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
# option. This file may not be copied, modified, or distributed
9+
# except according to those terms.
10+
11+
# Digs error codes out of files named 'diagnostics.rs' across
12+
# the tree, and ensures thare are no duplicates.
13+
14+
import sys, os, re
15+
16+
src_dir = sys.argv[1]
17+
18+
errcode_map = { }
19+
20+
for (dirpath, dirnames, filenames) in os.walk(src_dir):
21+
22+
if "src/test" in dirpath or "src/llvm" in dirpath:
23+
# Short circuit for fast
24+
continue
25+
26+
for filename in filenames:
27+
if filename != "diagnostics.rs":
28+
continue
29+
30+
path = os.path.join(dirpath, filename)
31+
line_num = 1
32+
with open(path, 'r') as f:
33+
for line in f:
34+
35+
p = re.compile("(E\d\d\d\d)")
36+
m = p.search(line)
37+
if not m is None:
38+
errcode = m.group(1)
39+
40+
new_record = [(errcode, path, line_num, line)]
41+
existing = errcode_map.get(errcode)
42+
if existing is not None:
43+
# This is a dupe
44+
errcode_map[errcode] = existing + new_record
45+
else:
46+
errcode_map[errcode] = new_record
47+
48+
line_num += 1
49+
50+
errors = False
51+
all_errors = []
52+
for errcode in errcode_map:
53+
entries = errcode_map[errcode]
54+
all_errors += [entries[0][0]]
55+
if len(entries) > 1:
56+
print "error: duplicate error code " + errcode
57+
for entry in entries:
58+
print entry[1] + ": " + str(entry[2])
59+
print entry[3]
60+
errors = True
61+
62+
print str(len(errcode_map)) + " error codes"
63+
64+
all_errors.sort()
65+
all_errors.reverse()
66+
67+
print "highest error code: " + all_errors[0]
68+
69+
if errors:
70+
sys.exit(1)

src/librustc/diagnostics.rs

Lines changed: 82 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,55 @@
1010

1111
#![allow(non_snake_case)]
1212

13-
register_diagnostic! { E0001, r##"
13+
register_long_diagnostics! {
14+
E0001: r##"
1415
This error suggests that the expression arm corresponding to the noted pattern
1516
will never be reached as for all possible values of the expression being matched,
1617
one of the preceeding patterns will match.
1718
1819
This means that perhaps some of the preceeding patterns are too general, this
1920
one is too specific or the ordering is incorrect.
20-
"## }
21+
"##,
22+
23+
E0003: r##"
24+
Not-a-Number (NaN) values can not be compared for equality and hence can never match
25+
the input to a match expression. To match against NaN values, you should instead use
26+
the `is_nan` method in a guard, as in: x if x.is_nan() => ...
27+
"##,
28+
29+
E0004: r##"
30+
This error indicates that the compiler can not guarantee a matching pattern for one
31+
or more possible inputs to a match expression. Guaranteed matches are required in order
32+
to assign values to match expressions, or alternatively, determine the flow of execution.
33+
34+
If you encounter this error you must alter your patterns so that every possible value of
35+
the input type is matched. For types with a small number of variants (like enums) you
36+
should probably cover all cases explicitly. Alternatively, the underscore `_` wildcard
37+
pattern can be added after all other patterns to match "anything else".
38+
"##,
39+
40+
// FIXME: Remove duplication here?
41+
E0005: r##"
42+
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
43+
name will be extracted in all cases. If you encounter this error you probably need
44+
to use a `match` or `if let` to deal with the possibility of failure.
45+
"##,
46+
47+
E0006: r##"
48+
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
49+
name will be extracted in all cases. If you encounter this error you probably need
50+
to use a `match` or `if let` to deal with the possibility of failure.
51+
"##
52+
}
2153

2254
register_diagnostics! {
2355
E0002,
24-
E0003,
25-
E0004,
26-
E0005,
27-
E0006,
2856
E0007,
2957
E0008,
3058
E0009,
3159
E0010,
3260
E0011,
3361
E0012,
34-
E0013,
3562
E0014,
3663
E0015,
3764
E0016,
@@ -49,24 +76,58 @@ register_diagnostics! {
4976
E0137,
5077
E0138,
5178
E0139,
52-
E0140,
5379
E0152,
54-
E0153,
55-
E0157,
5680
E0158,
5781
E0161,
5882
E0162,
5983
E0165,
60-
E0166,
61-
E0167,
62-
E0168,
63-
E0169,
6484
E0170,
65-
E0171,
66-
E0172,
67-
E0173,
68-
E0174,
69-
E0177,
70-
E0178,
71-
E0179
85+
E0261, // use of undeclared lifetime name
86+
E0262, // illegal lifetime parameter name
87+
E0263, // lifetime name declared twice in same scope
88+
E0264, // unknown external lang item
89+
E0265, // recursive constant
90+
E0266, // expected item
91+
E0267, // thing inside of a closure
92+
E0268, // thing outside of a loop
93+
E0269, // not all control paths return a value
94+
E0270, // computation may converge in a function marked as diverging
95+
E0271, // type mismatch resolving
96+
E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter
97+
E0273, // rustc_on_unimplemented must have named format arguments
98+
E0274, // rustc_on_unimplemented must have a value
99+
E0275, // overflow evaluating requirement
100+
E0276, // requirement appears on impl method but not on corresponding trait method
101+
E0277, // trait is not implemented for type
102+
E0278, // requirement is not satisfied
103+
E0279, // requirement is not satisfied
104+
E0280, // requirement is not satisfied
105+
E0281, // type implements trait but other trait is required
106+
E0282, // unable to infer enough type information about
107+
E0283, // cannot resolve type
108+
E0284, // cannot resolve type
109+
E0285, // overflow evaluation builtin bounds
110+
E0296, // malformed recursion limit attribute
111+
E0297, // refutable pattern in for loop binding
112+
E0298, // mismatched types between arms
113+
E0299, // mismatched types between arms
114+
E0300, // unexpanded macro
115+
E0301, // cannot mutable borrow in a pattern guard
116+
E0302, // cannot assign in a pattern guard
117+
E0303, // pattern bindings are not allowed after an `@`
118+
E0304, // expected signed integer constant
119+
E0305, // expected constant
120+
E0306, // expected positive integer for repeat count
121+
E0307, // expected constant integer for repeat count
122+
E0308,
123+
E0309, // thing may not live long enough
124+
E0310, // thing may not live long enough
125+
E0311, // thing may not live long enough
126+
E0312, // lifetime of reference outlives lifetime of borrowed content
127+
E0313, // lifetime of borrowed pointer outlives lifetime of captured variable
128+
E0314, // closure outlives stack frame
129+
E0315 // cannot invoke closure outside of its lifetime
72130
}
131+
132+
__build_diagnostic_array! { DIAGNOSTICS }
133+

src/librustc/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ extern crate test;
5454

5555
pub use rustc_llvm as llvm;
5656

57-
mod diagnostics;
57+
// NB: This module needs to be declared first so diagnostics are
58+
// registered before they are used.
59+
pub mod diagnostics;
5860

5961
pub mod back {
6062
pub use rustc_back::abi;
@@ -132,8 +134,6 @@ pub mod lib {
132134
pub use llvm;
133135
}
134136

135-
__build_diagnostic_array! { DIAGNOSTICS }
136-
137137
// A private module so that macro-expanded idents like
138138
// `::rustc::lint::Lint` will also work in `rustc` itself.
139139
//

src/librustc/middle/check_loop.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,12 @@ impl<'a> CheckLoopVisitor<'a> {
7373
match self.cx {
7474
Loop => {}
7575
Closure => {
76-
self.sess.span_err(span,
77-
&format!("`{}` inside of a closure", name)[]);
76+
span_err!(self.sess, span, E0267,
77+
"`{}` inside of a closure", name);
7878
}
7979
Normal => {
80-
self.sess.span_err(span,
81-
&format!("`{}` outside of loop", name)[]);
80+
span_err!(self.sess, span, E0268,
81+
"`{}` outside of loop", name);
8282
}
8383
}
8484
}

src/librustc/middle/check_match.rs

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,10 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
226226
ast::ExprForLoop(ref pat, _, _, _) => {
227227
let mut static_inliner = StaticInliner::new(cx.tcx);
228228
is_refutable(cx, &*static_inliner.fold_pat((*pat).clone()), |uncovered_pat| {
229-
cx.tcx.sess.span_err(
230-
pat.span,
231-
&format!("refutable pattern in `for` loop binding: \
229+
span_err!(cx.tcx.sess, pat.span, E0297,
230+
"refutable pattern in `for` loop binding: \
232231
`{}` not covered",
233-
pat_to_string(uncovered_pat))[]);
232+
pat_to_string(uncovered_pat));
234233
});
235234

236235
// Check legality of move bindings.
@@ -869,7 +868,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
869868
Some(true) => Some(vec![]),
870869
Some(false) => None,
871870
None => {
872-
cx.tcx.sess.span_err(pat_span, "mismatched types between arms");
871+
span_err!(cx.tcx.sess, pat_span, E0298, "mismatched types between arms");
873872
None
874873
}
875874
}
@@ -882,7 +881,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
882881
Some(true) => Some(vec![]),
883882
Some(false) => None,
884883
None => {
885-
cx.tcx.sess.span_err(pat_span, "mismatched types between arms");
884+
span_err!(cx.tcx.sess, pat_span, E0299, "mismatched types between arms");
886885
None
887886
}
888887
}
@@ -921,7 +920,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
921920
}
922921

923922
ast::PatMac(_) => {
924-
cx.tcx.sess.span_err(pat_span, "unexpanded macro");
923+
span_err!(cx.tcx.sess, pat_span, E0300, "unexpanded macro");
925924
None
926925
}
927926
};
@@ -1082,11 +1081,8 @@ impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> {
10821081
_: LoanCause) {
10831082
match kind {
10841083
MutBorrow => {
1085-
self.cx
1086-
.tcx
1087-
.sess
1088-
.span_err(span,
1089-
"cannot mutably borrow in a pattern guard")
1084+
span_err!(self.cx.tcx.sess, span, E0301,
1085+
"cannot mutably borrow in a pattern guard")
10901086
}
10911087
ImmBorrow | UniqueImmBorrow => {}
10921088
}
@@ -1095,10 +1091,7 @@ impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> {
10951091
fn mutate(&mut self, _: NodeId, span: Span, _: cmt, mode: MutateMode) {
10961092
match mode {
10971093
JustWrite | WriteAndRead => {
1098-
self.cx
1099-
.tcx
1100-
.sess
1101-
.span_err(span, "cannot assign in a pattern guard")
1094+
span_err!(self.cx.tcx.sess, span, E0302, "cannot assign in a pattern guard")
11021095
}
11031096
Init => {}
11041097
}
@@ -1120,7 +1113,7 @@ struct AtBindingPatternVisitor<'a, 'b:'a, 'tcx:'b> {
11201113
impl<'a, 'b, 'tcx, 'v> Visitor<'v> for AtBindingPatternVisitor<'a, 'b, 'tcx> {
11211114
fn visit_pat(&mut self, pat: &Pat) {
11221115
if !self.bindings_allowed && pat_is_binding(&self.cx.tcx.def_map, pat) {
1123-
self.cx.tcx.sess.span_err(pat.span,
1116+
span_err!(self.cx.tcx.sess, pat.span, E0303,
11241117
"pattern bindings are not allowed \
11251118
after an `@`");
11261119
}

src/librustc/middle/check_static_recursion.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ pub fn check_item_recursion<'a>(sess: &'a Session,
8383
impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> {
8484
fn visit_item(&mut self, it: &ast::Item) {
8585
if self.idstack.iter().any(|x| x == &(it.id)) {
86-
self.sess.span_err(self.root_it.span, "recursive constant");
86+
span_err!(self.sess, self.root_it.span, E0265, "recursive constant");
8787
return;
8888
}
8989
self.idstack.push(it.id);
@@ -103,9 +103,9 @@ impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> {
103103
self.visit_item(item),
104104
ast_map::NodeForeignItem(_) => {},
105105
_ => {
106-
self.sess.span_err(e.span,
107-
&format!("expected item, found {}",
108-
self.ast_map.node_to_string(def_id.node))[]);
106+
span_err!(self.sess, e.span, E0266,
107+
"expected item, found {}",
108+
self.ast_map.node_to_string(def_id.node));
109109
return;
110110
},
111111
}

0 commit comments

Comments
 (0)