Skip to content

Make error code registration work again. #19624 #21289

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 22, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mk/tests.mk
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ tidy:
| grep '^$(S)src/libbacktrace' -v \
| grep '^$(S)src/rust-installer' -v \
| xargs $(CFG_PYTHON) $(S)src/etc/check-binaries.py
$(Q) $(CFG_PYTHON) $(S)src/etc/errorck.py $(S)src/


endif
Expand Down
70 changes: 70 additions & 0 deletions src/etc/errorck.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Copyright 2015 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.

# Digs error codes out of files named 'diagnostics.rs' across
# the tree, and ensures thare are no duplicates.

import sys, os, re

src_dir = sys.argv[1]

errcode_map = { }

for (dirpath, dirnames, filenames) in os.walk(src_dir):

if "src/test" in dirpath or "src/llvm" in dirpath:
# Short circuit for fast
continue

for filename in filenames:
if filename != "diagnostics.rs":
continue

path = os.path.join(dirpath, filename)
line_num = 1
with open(path, 'r') as f:
for line in f:

p = re.compile("(E\d\d\d\d)")
m = p.search(line)
if not m is None:
errcode = m.group(1)

new_record = [(errcode, path, line_num, line)]
existing = errcode_map.get(errcode)
if existing is not None:
# This is a dupe
errcode_map[errcode] = existing + new_record
else:
errcode_map[errcode] = new_record

line_num += 1

errors = False
all_errors = []
for errcode in errcode_map:
entries = errcode_map[errcode]
all_errors += [entries[0][0]]
if len(entries) > 1:
print "error: duplicate error code " + errcode
for entry in entries:
print entry[1] + ": " + str(entry[2])
print entry[3]
errors = True

print str(len(errcode_map)) + " error codes"

all_errors.sort()
all_errors.reverse()

print "highest error code: " + all_errors[0]

if errors:
sys.exit(1)
103 changes: 82 additions & 21 deletions src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,55 @@

#![allow(non_snake_case)]

register_diagnostic! { E0001, r##"
register_long_diagnostics! {
E0001: r##"
This error suggests that the expression arm corresponding to the noted pattern
will never be reached as for all possible values of the expression being matched,
one of the preceeding patterns will match.

This means that perhaps some of the preceeding patterns are too general, this
one is too specific or the ordering is incorrect.
"## }
"##,

E0003: r##"
Not-a-Number (NaN) values can not be compared for equality and hence can never match
the input to a match expression. To match against NaN values, you should instead use
the `is_nan` method in a guard, as in: x if x.is_nan() => ...
"##,

E0004: r##"
This error indicates that the compiler can not guarantee a matching pattern for one
or more possible inputs to a match expression. Guaranteed matches are required in order
to assign values to match expressions, or alternatively, determine the flow of execution.

If you encounter this error you must alter your patterns so that every possible value of
the input type is matched. For types with a small number of variants (like enums) you
should probably cover all cases explicitly. Alternatively, the underscore `_` wildcard
pattern can be added after all other patterns to match "anything else".
"##,

// FIXME: Remove duplication here?
E0005: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0006: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##
}

register_diagnostics! {
E0002,
E0003,
E0004,
E0005,
E0006,
E0007,
E0008,
E0009,
E0010,
E0011,
E0012,
E0013,
E0014,
E0015,
E0016,
Expand All @@ -49,24 +76,58 @@ register_diagnostics! {
E0137,
E0138,
E0139,
E0140,
E0152,
E0153,
E0157,
E0158,
E0161,
E0162,
E0165,
E0166,
E0167,
E0168,
E0169,
E0170,
E0171,
E0172,
E0173,
E0174,
E0177,
E0178,
E0179
E0261, // use of undeclared lifetime name
E0262, // illegal lifetime parameter name
E0263, // lifetime name declared twice in same scope
E0264, // unknown external lang item
E0265, // recursive constant
E0266, // expected item
E0267, // thing inside of a closure
E0268, // thing outside of a loop
E0269, // not all control paths return a value
E0270, // computation may converge in a function marked as diverging
E0271, // type mismatch resolving
E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter
E0273, // rustc_on_unimplemented must have named format arguments
E0274, // rustc_on_unimplemented must have a value
E0275, // overflow evaluating requirement
E0276, // requirement appears on impl method but not on corresponding trait method
E0277, // trait is not implemented for type
E0278, // requirement is not satisfied
E0279, // requirement is not satisfied
E0280, // requirement is not satisfied
E0281, // type implements trait but other trait is required
E0282, // unable to infer enough type information about
E0283, // cannot resolve type
E0284, // cannot resolve type
E0285, // overflow evaluation builtin bounds
E0296, // malformed recursion limit attribute
E0297, // refutable pattern in for loop binding
E0298, // mismatched types between arms
E0299, // mismatched types between arms
E0300, // unexpanded macro
E0301, // cannot mutable borrow in a pattern guard
E0302, // cannot assign in a pattern guard
E0303, // pattern bindings are not allowed after an `@`
E0304, // expected signed integer constant
E0305, // expected constant
E0306, // expected positive integer for repeat count
E0307, // expected constant integer for repeat count
E0308,
E0309, // thing may not live long enough
E0310, // thing may not live long enough
E0311, // thing may not live long enough
E0312, // lifetime of reference outlives lifetime of borrowed content
E0313, // lifetime of borrowed pointer outlives lifetime of captured variable
E0314, // closure outlives stack frame
E0315 // cannot invoke closure outside of its lifetime
}

__build_diagnostic_array! { DIAGNOSTICS }

6 changes: 3 additions & 3 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ extern crate test;

pub use rustc_llvm as llvm;

mod diagnostics;
// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
pub mod diagnostics;

pub mod back {
pub use rustc_back::abi;
Expand Down Expand Up @@ -132,8 +134,6 @@ pub mod lib {
pub use llvm;
}

__build_diagnostic_array! { DIAGNOSTICS }

// A private module so that macro-expanded idents like
// `::rustc::lint::Lint` will also work in `rustc` itself.
//
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/check_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ impl<'a> CheckLoopVisitor<'a> {
match self.cx {
Loop => {}
Closure => {
self.sess.span_err(span,
&format!("`{}` inside of a closure", name)[]);
span_err!(self.sess, span, E0267,
"`{}` inside of a closure", name);
}
Normal => {
self.sess.span_err(span,
&format!("`{}` outside of loop", name)[]);
span_err!(self.sess, span, E0268,
"`{}` outside of loop", name);
}
}
}
Expand Down
27 changes: 10 additions & 17 deletions src/librustc/middle/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,10 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
ast::ExprForLoop(ref pat, _, _, _) => {
let mut static_inliner = StaticInliner::new(cx.tcx);
is_refutable(cx, &*static_inliner.fold_pat((*pat).clone()), |uncovered_pat| {
cx.tcx.sess.span_err(
pat.span,
&format!("refutable pattern in `for` loop binding: \
span_err!(cx.tcx.sess, pat.span, E0297,
"refutable pattern in `for` loop binding: \
`{}` not covered",
pat_to_string(uncovered_pat))[]);
pat_to_string(uncovered_pat));
});

// Check legality of move bindings.
Expand Down Expand Up @@ -869,7 +868,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
Some(true) => Some(vec![]),
Some(false) => None,
None => {
cx.tcx.sess.span_err(pat_span, "mismatched types between arms");
span_err!(cx.tcx.sess, pat_span, E0298, "mismatched types between arms");
None
}
}
Expand All @@ -882,7 +881,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
Some(true) => Some(vec![]),
Some(false) => None,
None => {
cx.tcx.sess.span_err(pat_span, "mismatched types between arms");
span_err!(cx.tcx.sess, pat_span, E0299, "mismatched types between arms");
None
}
}
Expand Down Expand Up @@ -921,7 +920,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
}

ast::PatMac(_) => {
cx.tcx.sess.span_err(pat_span, "unexpanded macro");
span_err!(cx.tcx.sess, pat_span, E0300, "unexpanded macro");
None
}
};
Expand Down Expand Up @@ -1082,11 +1081,8 @@ impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> {
_: LoanCause) {
match kind {
MutBorrow => {
self.cx
.tcx
.sess
.span_err(span,
"cannot mutably borrow in a pattern guard")
span_err!(self.cx.tcx.sess, span, E0301,
"cannot mutably borrow in a pattern guard")
}
ImmBorrow | UniqueImmBorrow => {}
}
Expand All @@ -1095,10 +1091,7 @@ impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> {
fn mutate(&mut self, _: NodeId, span: Span, _: cmt, mode: MutateMode) {
match mode {
JustWrite | WriteAndRead => {
self.cx
.tcx
.sess
.span_err(span, "cannot assign in a pattern guard")
span_err!(self.cx.tcx.sess, span, E0302, "cannot assign in a pattern guard")
}
Init => {}
}
Expand All @@ -1120,7 +1113,7 @@ struct AtBindingPatternVisitor<'a, 'b:'a, 'tcx:'b> {
impl<'a, 'b, 'tcx, 'v> Visitor<'v> for AtBindingPatternVisitor<'a, 'b, 'tcx> {
fn visit_pat(&mut self, pat: &Pat) {
if !self.bindings_allowed && pat_is_binding(&self.cx.tcx.def_map, pat) {
self.cx.tcx.sess.span_err(pat.span,
span_err!(self.cx.tcx.sess, pat.span, E0303,
"pattern bindings are not allowed \
after an `@`");
}
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/check_static_recursion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ pub fn check_item_recursion<'a>(sess: &'a Session,
impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> {
fn visit_item(&mut self, it: &ast::Item) {
if self.idstack.iter().any(|x| x == &(it.id)) {
self.sess.span_err(self.root_it.span, "recursive constant");
span_err!(self.sess, self.root_it.span, E0265, "recursive constant");
return;
}
self.idstack.push(it.id);
Expand All @@ -103,9 +103,9 @@ impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> {
self.visit_item(item),
ast_map::NodeForeignItem(_) => {},
_ => {
self.sess.span_err(e.span,
&format!("expected item, found {}",
self.ast_map.node_to_string(def_id.node))[]);
span_err!(self.sess, e.span, E0266,
"expected item, found {}",
self.ast_map.node_to_string(def_id.node));
return;
},
}
Expand Down
Loading