Skip to content

Commit

Permalink
Convert a first batch of diagnostics to have error codes
Browse files Browse the repository at this point in the history
  • Loading branch information
Jakub Wieczorek committed Jul 12, 2014
1 parent 350f3aa commit a5fe176
Show file tree
Hide file tree
Showing 11 changed files with 410 additions and 390 deletions.
96 changes: 96 additions & 0 deletions src/librustc/diagnostics.rs
Expand Up @@ -16,3 +16,99 @@ register_diagnostic!(E0001, r##"
This means that perhaps some of the preceeding patterns are too general, this
one is too specific or the ordering is incorrect.
"##)

register_diagnostics!(
E0002,
E0003,
E0004,
E0005,
E0006,
E0007,
E0008,
E0009,
E0010,
E0011,
E0012,
E0013,
E0014,
E0015,
E0016,
E0017,
E0018,
E0019,
E0020,
E0021,
E0022,
E0023,
E0024,
E0025,
E0026,
E0027,
E0028,
E0029,
E0030,
E0031,
E0032,
E0033,
E0034,
E0035,
E0036,
E0037,
E0038,
E0039,
E0040,
E0041,
E0042,
E0043,
E0044,
E0045,
E0046,
E0047,
E0048,
E0049,
E0050,
E0051,
E0052,
E0053,
E0054,
E0055,
E0056,
E0057,
E0058,
E0059,
E0060,
E0061,
E0062,
E0063,
E0064,
E0065,
E0066,
E0067,
E0068,
E0069,
E0070,
E0071,
E0072,
E0073,
E0074,
E0075,
E0076,
E0077,
E0078,
E0079,
E0080,
E0081,
E0082,
E0083,
E0084,
E0085,
E0086,
E0087,
E0088,
E0089,
E0090,
E0091,
E0092,
E0093,
E0094
)
3 changes: 3 additions & 0 deletions src/librustc/driver/session.rs
Expand Up @@ -85,6 +85,9 @@ impl Session {
pub fn span_warn(&self, sp: Span, msg: &str) {
self.diagnostic().span_warn(sp, msg)
}
pub fn span_warn_with_code(&self, sp: Span, msg: &str, code: &str) {
self.diagnostic().span_warn_with_code(sp, msg, code)
}
pub fn warn(&self, msg: &str) {
self.diagnostic().handler().warn(msg)
}
Expand Down
51 changes: 22 additions & 29 deletions src/librustc/middle/check_const.rs
Expand Up @@ -87,28 +87,25 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
match e.node {
ExprUnary(UnDeref, _) => { }
ExprUnary(UnBox, _) | ExprUnary(UnUniq, _) => {
v.tcx.sess.span_err(e.span,
"cannot do allocations in constant expressions");
span_err!(v.tcx.sess, e.span, E0010, "cannot do allocations in constant expressions");
return;
}
ExprLit(lit) if ast_util::lit_is_str(lit) => {}
ExprBinary(..) | ExprUnary(..) => {
let method_call = typeck::MethodCall::expr(e.id);
if v.tcx.method_map.borrow().contains_key(&method_call) {
v.tcx.sess.span_err(e.span, "user-defined operators are not \
allowed in constant expressions");
span_err!(v.tcx.sess, e.span, E0011,
"user-defined operators are not allowed in constant expressions");
}
}
ExprLit(_) => (),
ExprCast(_, _) => {
let ety = ty::expr_ty(v.tcx, e);
if !ty::type_is_numeric(ety) && !ty::type_is_unsafe_ptr(ety) {
v.tcx
.sess
.span_err(e.span,
format!("can not cast to `{}` in a constant \
expression",
ppaux::ty_to_string(v.tcx, ety)).as_slice())
span_err!(v.tcx.sess, e.span, E0012,
"can not cast to `{}` in a constant expression",
ppaux::ty_to_string(v.tcx, ety)
);
}
}
ExprPath(ref pth) => {
Expand All @@ -117,9 +114,8 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
// foo::<bar> in a const. Currently that is only done on
// a path in trans::callee that only works in block contexts.
if !pth.segments.iter().all(|segment| segment.types.is_empty()) {
v.tcx.sess.span_err(e.span,
"paths in constants may only refer to \
items without type parameters");
span_err!(v.tcx.sess, e.span, E0013,
"paths in constants may only refer to items without type parameters");
}
match v.tcx.def_map.borrow().find(&e.id) {
Some(&DefStatic(..)) |
Expand All @@ -129,9 +125,8 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {

Some(&def) => {
debug!("(checking const) found bad def: {:?}", def);
v.tcx.sess.span_err(e.span,
"paths in constants may only refer to \
constants or functions");
span_err!(v.tcx.sess, e.span, E0014,
"paths in constants may only refer to constants or functions");
}
None => {
v.tcx.sess.span_bug(e.span, "unbound path in const?!");
Expand All @@ -143,19 +138,17 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
Some(&DefStruct(..)) => {} // OK.
Some(&DefVariant(..)) => {} // OK.
_ => {
v.tcx.sess.span_err(e.span,
"function calls in constants are limited to \
struct and enum constructors");
span_err!(v.tcx.sess, e.span, E0015,
"function calls in constants are limited to struct and enum constructors");
}
}
}
ExprBlock(ref block) => {
// Check all statements in the block
for stmt in block.stmts.iter() {
let block_span_err = |span|
v.tcx.sess.span_err(span,
"blocks in constants are limited to \
items and tail expressions");
span_err!(v.tcx.sess, span, E0016,
"blocks in constants are limited to items and tail expressions");
match stmt.node {
StmtDecl(ref span, _) => {
match span.node {
Expand Down Expand Up @@ -187,18 +180,18 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
ExprRepeat(..) |
ExprStruct(..) => { }
ExprAddrOf(..) => {
v.tcx.sess.span_err(e.span,
"references in constants may only refer to \
immutable values");
span_err!(v.tcx.sess, e.span, E0017,
"references in constants may only refer to immutable values");
},
ExprVstore(_, ExprVstoreUniq) => {
v.tcx.sess.span_err(e.span, "cannot allocate vectors in constant expressions")
span_err!(v.tcx.sess, e.span, E0018,
"cannot allocate vectors in constant expressions");
},

_ => {
v.tcx.sess.span_err(e.span,
"constant contains unimplemented expression type");
return;
span_err!(v.tcx.sess, e.span, E0019,
"constant contains unimplemented expression type");
return;
}
}
}
Expand Down
55 changes: 24 additions & 31 deletions src/librustc/middle/check_match.rs
Expand Up @@ -142,15 +142,16 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &Expr) {
// Finally, check if the whole match expression is exhaustive.
// Check for empty enum, because is_useful only works on inhabited types.
let pat_ty = node_id_to_type(cx.tcx, scrut.id);
if (*arms).is_empty() {
if !type_is_empty(cx.tcx, pat_ty) {
// We know the type is inhabited, so this must be wrong
cx.tcx.sess.span_err(ex.span, format!("non-exhaustive patterns: \
type {} is non-empty",
ty_to_string(cx.tcx, pat_ty)).as_slice());
}
// If the type *is* empty, it's vacuously exhaustive
return;
if arms.is_empty() {
if !type_is_empty(cx.tcx, pat_ty) {
// We know the type is inhabited, so this must be wrong
span_err!(cx.tcx.sess, ex.span, E0002,
"non-exhaustive patterns: type {} is non-empty",
ty_to_string(cx.tcx, pat_ty)
);
}
// If the type *is* empty, it's vacuously exhaustive
return;
}
let m: Matrix = Matrix(arms
.iter()
Expand Down Expand Up @@ -186,8 +187,9 @@ fn check_arms(cx: &MatchCheckCtxt, arms: &[Arm]) {

walk_pat(&**pat, |p| {
if pat_matches_nan(p) {
cx.tcx.sess.span_warn(p.span, "unmatchable NaN in pattern, \
use the is_nan method in a guard instead");
span_warn!(cx.tcx.sess, p.span, E0003,
"unmatchable NaN in pattern, use the is_nan method in a guard instead"
);
}
true
});
Expand Down Expand Up @@ -222,9 +224,10 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, m: &Matrix) {
[] => wild(),
_ => unreachable!()
};
let msg = format!("non-exhaustive patterns: `{0}` not covered",
pat_to_string(&*witness));
cx.tcx.sess.span_err(sp, msg.as_slice());
span_err!(cx.tcx.sess, sp, E0004,
"non-exhaustive patterns: `{}` not covered",
pat_to_string(&*witness)
);
}
NotUseful => {
// This is good, wildcard pattern isn't reachable
Expand Down Expand Up @@ -779,11 +782,10 @@ fn check_local(cx: &mut MatchCheckCtxt, loc: &Local) {

match is_refutable(cx, loc.pat) {
Some(pat) => {
let msg = format!(
span_err!(cx.tcx.sess, loc.pat.span, E0005,
"refutable pattern in {} binding: `{}` not covered",
name, pat_to_string(&*pat)
);
cx.tcx.sess.span_err(loc.pat.span, msg.as_slice());
},
None => ()
}
Expand All @@ -801,11 +803,10 @@ fn check_fn(cx: &mut MatchCheckCtxt,
for input in decl.inputs.iter() {
match is_refutable(cx, input.pat) {
Some(pat) => {
let msg = format!(
span_err!(cx.tcx.sess, input.pat.span, E0006,
"refutable pattern in function argument: `{}` not covered",
pat_to_string(&*pat)
);
cx.tcx.sess.span_err(input.pat.span, msg.as_slice());
},
None => ()
}
Expand Down Expand Up @@ -850,21 +851,13 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,

// x @ Foo(..) is legal, but x @ Foo(y) isn't.
if sub.map_or(false, |p| pat_contains_bindings(def_map, &*p)) {
tcx.sess.span_err(
p.span,
"cannot bind by-move with sub-bindings");
span_err!(cx.tcx.sess, p.span, E0007, "cannot bind by-move with sub-bindings");
} else if has_guard {
tcx.sess.span_err(
p.span,
"cannot bind by-move into a pattern guard");
span_err!(cx.tcx.sess, p.span, E0008, "cannot bind by-move into a pattern guard");
} else if by_ref_span.is_some() {
tcx.sess.span_err(
p.span,
"cannot bind by-move and by-ref \
in the same pattern");
tcx.sess.span_note(
by_ref_span.unwrap(),
"by-ref binding occurs here");
span_err!(cx.tcx.sess, p.span, E0009,
"cannot bind by-move and by-ref in the same pattern");
span_note!(cx.tcx.sess, by_ref_span.unwrap(), "by-ref binding occurs here");
}
};

Expand Down
12 changes: 6 additions & 6 deletions src/librustc/middle/check_static.rs
Expand Up @@ -112,18 +112,18 @@ impl<'a> Visitor<bool> for CheckStaticVisitor<'a> {
visit::walk_expr(self, e, is_const);
}
ast::ExprVstore(_, ast::ExprVstoreMutSlice) => {
self.tcx.sess.span_err(e.span,
"static items are not allowed to have mutable slices");
span_err!(self.tcx.sess, e.span, E0020,
"static items are not allowed to have mutable slices");
},
ast::ExprUnary(ast::UnBox, _) => {
self.tcx.sess.span_err(e.span,
"static items are not allowed to have managed pointers");
span_err!(self.tcx.sess, e.span, E0021,
"static items are not allowed to have managed pointers");
}
ast::ExprBox(..) |
ast::ExprUnary(ast::UnUniq, _) |
ast::ExprVstore(_, ast::ExprVstoreUniq) => {
self.tcx.sess.span_err(e.span,
"static items are not allowed to have custom pointers");
span_err!(self.tcx.sess, e.span, E0022,
"static items are not allowed to have custom pointers");
}
_ => {
let node_ty = ty::node_id_to_type(self.tcx, e.id);
Expand Down

10 comments on commit a5fe176

@bors
Copy link
Contributor

@bors bors commented on a5fe176 Jul 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on a5fe176 Jul 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging jakub-/rust/diagnostics = a5fe176 into auto

@bors
Copy link
Contributor

@bors bors commented on a5fe176 Jul 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jakub-/rust/diagnostics = a5fe176 merged ok, testing candidate = b40bdaba

@brson
Copy link
Contributor

@brson brson commented on a5fe176 Jul 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors: retry

@bors
Copy link
Contributor

@bors bors commented on a5fe176 Jul 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on a5fe176 Jul 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging jakub-/rust/diagnostics = a5fe176 into auto

@bors
Copy link
Contributor

@bors bors commented on a5fe176 Jul 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jakub-/rust/diagnostics = a5fe176 merged ok, testing candidate = de111e6

@bors
Copy link
Contributor

@bors bors commented on a5fe176 Jul 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = de111e6

Please sign in to comment.