]> git.lizzy.rs Git - rust.git/commitdiff
Convert a first batch of diagnostics to have error codes
authorJakub Wieczorek <jakub@jakub.cc>
Fri, 11 Jul 2014 16:54:01 +0000 (18:54 +0200)
committerJakub Wieczorek <jakub@jakub.cc>
Sat, 12 Jul 2014 19:53:34 +0000 (21:53 +0200)
src/librustc/diagnostics.rs
src/librustc/driver/session.rs
src/librustc/middle/check_const.rs
src/librustc/middle/check_match.rs
src/librustc/middle/check_static.rs
src/librustc/middle/typeck/check/_match.rs
src/librustc/middle/typeck/check/method.rs
src/librustc/middle/typeck/check/mod.rs
src/libsyntax/diagnostic.rs
src/libsyntax/diagnostics/macros.rs
src/libsyntax/diagnostics/plugin.rs

index 0499795f890fd20960c08b00fb30cfbd35400d86..5f3bbf481056a4dc5662e616f39e7a4c58b55171 100644 (file)
     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
+)
index 313b2bd6bf0d46e7c1db8e5ee77c81a50d870b36..135e21e4e018463bb812176a1db0fc8da812b251 100644 (file)
@@ -85,6 +85,9 @@ pub fn abort_if_errors(&self) {
     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)
     }
index 33bf6ceed4f2b848d9811072495d8b0d0dd47dad..283d667f3a8032973ca4037ca30009d915cc5c35 100644 (file)
@@ -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) => {
@@ -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(..)) |
@@ -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?!");
@@ -143,9 +138,8 @@ 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");
                 }
             }
           }
@@ -153,9 +147,8 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
             // 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 {
@@ -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;
           }
         }
     }
index f31c247abd38c3c83935d0d5bad13221db1ffddf..832b222ef1641200c1e38618a25bf1156ddb415c 100644 (file)
@@ -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()
@@ -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
             });
@@ -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
@@ -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 => ()
     }
@@ -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 => ()
         }
@@ -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");
         }
     };
 
index 1e948afb7018fe745ffc05f1e5db7dc33291e65d..8985e633ad464b6f057db2f06c1e46dee83ccea2 100644 (file)
@@ -112,18 +112,18 @@ fn visit_expr(&mut self, e: &ast::Expr, is_const: bool) {
                 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);
index 2232cc4965785fcab7d6aa3b4f787a27c6665c48..170f850328eb0af81c9f99ace31072750d47c500 100644 (file)
@@ -253,14 +253,10 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: &ast::Pat, path: &ast::Path,
     if arg_len > 0 {
         // N-ary variant.
         if arg_len != subpats_len {
-            let s = format!("this pattern has {} field{}, \
-                             but the corresponding {} has {} field{}",
-                         subpats_len,
-                         if subpats_len == 1 {""} else {"s"},
-                         kind_name,
-                         arg_len,
-                         if arg_len == 1 {""} else {"s"});
-            tcx.sess.span_err(pat.span, s.as_slice());
+            span_err!(tcx.sess, pat.span, E0023,
+                      "this pattern has {} field{}, but the corresponding {} has {} field{}",
+                      subpats_len, if subpats_len == 1 {""} else {"s"},
+                      kind_name, arg_len, if arg_len == 1 {""} else {"s"});
             error_happened = true;
         }
 
@@ -272,12 +268,10 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: &ast::Pat, path: &ast::Path,
             }
         }
     } else if subpats_len > 0 {
-        tcx.sess.span_err(pat.span,
-                          format!("this pattern has {} field{}, \
-                                   but the corresponding {} has no fields",
-                               subpats_len,
-                               if subpats_len == 1 {""} else {"s"},
-                               kind_name).as_slice());
+        span_err!(tcx.sess, pat.span, E0024,
+                  "this pattern has {} field{}, but the corresponding {} has no fields",
+                  subpats_len, if subpats_len == 1 {""} else {"s"},
+                  kind_name);
         error_happened = true;
     }
 
@@ -321,9 +315,9 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt,
                 // Check the pattern anyway, so that attempts to look
                 // up its type won't fail
                 check_pat(pcx, &*field.pat, ty::mk_err());
-                tcx.sess.span_err(span,
-                    format!("field `{}` bound twice in pattern",
-                            token::get_ident(field.ident)).as_slice());
+                span_err!(tcx.sess, span, E0025,
+                    "field `{}` bound twice in pattern",
+                    token::get_ident(field.ident));
             }
             Some(&(index, ref mut used)) => {
                 *used = true;
@@ -339,10 +333,10 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt,
                 // Check the pattern anyway, so that attempts to look
                 // up its type won't fail
                 check_pat(pcx, &*field.pat, ty::mk_err());
-                tcx.sess.span_err(span,
-                    format!("struct `{}` does not have a field named `{}`",
-                            ty::item_path_str(tcx, class_id),
-                            token::get_ident(field.ident)).as_slice());
+                span_err!(tcx.sess, span, E0026,
+                    "struct `{}` does not have a field named `{}`",
+                    ty::item_path_str(tcx, class_id),
+                    token::get_ident(field.ident));
             }
         }
     }
@@ -353,11 +347,9 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt,
             if found_fields.contains(&i) {
                 continue;
             }
-
-            tcx.sess
-               .span_err(span,
-                         format!("pattern does not mention field `{}`",
-                                 token::get_name(field.name)).as_slice());
+            span_err!(tcx.sess, span, E0027,
+                "pattern does not mention field `{}`",
+                token::get_name(field.name));
         }
     }
 }
@@ -400,11 +392,9 @@ pub fn check_struct_like_enum_variant_pat(pcx: &pat_ctxt,
         }
         Some(&def::DefStruct(..)) | Some(&def::DefVariant(..)) => {
             let name = pprust::path_to_string(path);
-            tcx.sess.span_err(span,
-                              format!("mismatched types: expected `{}` but \
-                                       found `{}`",
-                                      fcx.infcx().ty_to_string(expected),
-                                      name).as_slice());
+            span_err!(tcx.sess, span, E0028,
+                "mismatched types: expected `{}` but found `{}`",
+                fcx.infcx().ty_to_string(expected), name);
         }
         _ => {
             tcx.sess.span_bug(span, "resolve didn't write in variant");
@@ -441,16 +431,16 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
         {
             // no-op
         } else if !ty::type_is_numeric(b_ty) && !ty::type_is_char(b_ty) {
-            tcx.sess.span_err(pat.span,
+            span_err!(tcx.sess, begin.span, E0029,
                 "only char and numeric types are allowed in range");
         } else {
             match valid_range_bounds(fcx.ccx, &**begin, &**end) {
                 Some(false) => {
-                    tcx.sess.span_err(begin.span,
+                    span_err!(tcx.sess, begin.span, E0030,
                         "lower range bound must be less than upper");
                 },
                 None => {
-                    tcx.sess.span_err(begin.span,
+                    span_err!(tcx.sess, begin.span, E0031,
                         "mismatched types in range");
                 },
                 _ => { },
@@ -521,13 +511,10 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
                     ty::ty_to_def_id(
                         ty::lookup_item_type(tcx, item_did).ty).unwrap();
                 if struct_did != cid {
-                    tcx.sess
-                       .span_err(path.span,
-                                 format!("`{}` does not name the \
-                                          structure `{}`",
-                                         pprust::path_to_string(path),
-                                         fcx.infcx()
-                                            .ty_to_string(expected)).as_slice())
+                    span_err!(tcx.sess, pat.span, E0032,
+                        "`{}` does not name the structure `{}`",
+                        pprust::path_to_string(path),
+                        fcx.infcx().ty_to_string(expected));
                 }
 
                 check_struct_pat(pcx, pat.id, pat.span, expected, path,
@@ -744,10 +731,9 @@ fn check_pointer_pat(pcx: &pat_ctxt,
                 // This is "x = SomeTrait" being reduced from
                 // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
                 check_pat(pcx, inner, ty::mk_err());
-                tcx.sess.span_err(
-                    span,
-                    format!("type `{}` cannot be dereferenced",
-                            fcx.infcx().ty_to_string(expected)).as_slice());
+                span_err!(tcx.sess, span, E0033,
+                    "type `{}` cannot be dereferenced",
+                    fcx.infcx().ty_to_string(expected));
                 fcx.write_error(pat_id);
             }
             _ => {
index a184ecac9dea669196a66ce619dc40341f6a9586..4787837093844233fd86e2b65361cd293be94862 100644 (file)
@@ -1041,8 +1041,7 @@ fn consider_candidates(&self, rcvr_ty: ty::t,
         }
 
         if relevant_candidates.len() > 1 {
-            self.tcx().sess.span_err(
-                self.span,
+            span_err!(self.tcx().sess, self.span, E0034,
                 "multiple applicable methods in scope");
             for (idx, candidate) in relevant_candidates.iter().enumerate() {
                 self.report_candidate(idx, &candidate.origin);
@@ -1112,13 +1111,11 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
             if num_supplied_tps == 0u {
                 self.fcx.infcx().next_ty_vars(num_method_tps)
             } else if num_method_tps == 0u {
-                tcx.sess.span_err(
-                    self.span,
-                    "this method does not take type parameters");
+                span_err!(tcx.sess, self.span, E0035,
+                    "does not take type parameters");
                 self.fcx.infcx().next_ty_vars(num_method_tps)
             } else if num_supplied_tps != num_method_tps {
-                tcx.sess.span_err(
-                    self.span,
+                span_err!(tcx.sess, self.span, E0036,
                     "incorrect number of type parameters given for this method");
                 self.fcx.infcx().next_ty_vars(num_method_tps)
             } else {
@@ -1221,10 +1218,8 @@ fn enforce_object_limitations(&self, candidate: &Candidate) {
 
         match candidate.method_ty.explicit_self {
             ast::SelfStatic => { // reason (a) above
-                self.tcx().sess.span_err(
-                    self.span,
-                    "cannot call a method without a receiver \
-                     through an object");
+                span_err!(self.tcx().sess, self.span, E0037,
+                    "cannot call a method without a receiver through an object");
             }
 
             ast::SelfValue(_) | ast::SelfRegion(..) | ast::SelfUniq(_) => {}
@@ -1233,8 +1228,7 @@ fn enforce_object_limitations(&self, candidate: &Candidate) {
         // reason (a) above
         let check_for_self_ty = |ty| {
             if ty::type_has_self(ty) {
-                self.tcx().sess.span_err(
-                    self.span,
+                span_err!(self.tcx().sess, self.span, E0038,
                     "cannot call a method whose type contains a \
                      self-type through an object");
                 true
@@ -1256,8 +1250,7 @@ fn enforce_object_limitations(&self, candidate: &Candidate) {
 
         if candidate.method_ty.generics.has_type_params(subst::FnSpace) {
             // reason (b) above
-            self.tcx().sess.span_err(
-                self.span,
+            span_err!(self.tcx().sess, self.span, E0039,
                 "cannot call a generic method through an object");
         }
     }
@@ -1279,8 +1272,8 @@ fn enforce_drop_trait_limitations(&self, candidate: &Candidate) {
         }
 
         if bad {
-            self.tcx().sess.span_err(self.span,
-                                     "explicit call to destructor");
+            span_err!(self.tcx().sess, self.span, E0040,
+                "explicit call to destructor");
         }
     }
 
@@ -1425,28 +1418,22 @@ fn report_static_candidate(&self, idx: uint, did: DefId) {
         } else {
             self.span
         };
-        self.tcx().sess.span_note(
-            span,
-            format!("candidate #{} is `{}`",
-                    idx + 1u,
-                    ty::item_path_str(self.tcx(), did)).as_slice());
+        span_note!(self.tcx().sess, span,
+            "candidate #{} is `{}`",
+            idx + 1u, ty::item_path_str(self.tcx(), did));
     }
 
     fn report_param_candidate(&self, idx: uint, did: DefId) {
-        self.tcx().sess.span_note(
-            self.span,
-            format!("candidate #{} derives from the bound `{}`",
-                    idx + 1u,
-                    ty::item_path_str(self.tcx(), did)).as_slice());
+        span_note!(self.tcx().sess, self.span,
+            "candidate #{} derives from the bound `{}`",
+            idx + 1u, ty::item_path_str(self.tcx(), did));
     }
 
     fn report_trait_candidate(&self, idx: uint, did: DefId) {
-        self.tcx().sess.span_note(
-            self.span,
-            format!("candidate #{} derives from the type of the receiver, \
-                     which is the trait `{}`",
-                    idx + 1u,
-                    ty::item_path_str(self.tcx(), did)).as_slice());
+        span_note!(self.tcx().sess, self.span,
+            "candidate #{} derives from the type of the receiver, \
+            which is the trait `{}`",
+            idx + 1u, ty::item_path_str(self.tcx(), did));
     }
 
     fn infcx(&'a self) -> &'a infer::InferCtxt<'a> {
index cdf434f4099dc831ab493330caace47c54738a92..7a4451c38f484f9cab8cb805ce8dd82e6de3fdbf 100644 (file)
@@ -569,11 +569,10 @@ fn check_for_field_shadowing(tcx: &ty::ctxt,
             for f in fields.iter() {
                 match super_fields.iter().find(|sf| f.name == sf.name) {
                     Some(prev_field) => {
-                        tcx.sess.span_err(span_for_field(tcx, f, id),
-                            format!("field `{}` hides field declared in \
-                                     super-struct",
-                                    token::get_name(f.name)).as_slice());
-                        tcx.sess.span_note(span_for_field(tcx, prev_field, parent_id),
+                        span_err!(tcx.sess, span_for_field(tcx, f, id), E0041,
+                            "field `{}` hides field declared in super-struct",
+                            token::get_name(f.name));
+                        span_note!(tcx.sess, span_for_field(tcx, prev_field, parent_id),
                             "previously declared here");
                     },
                     None => {}
@@ -595,16 +594,16 @@ fn check_fields_sized(tcx: &ty::ctxt,
         if !ty::type_is_sized(tcx, t) {
             match f.node.kind {
                 ast::NamedField(ident, _) => {
-                    tcx.sess.span_err(
-                        f.span,
-                        format!("type `{}` is dynamically sized. \
-                                 dynamically sized types may only \
-                                 appear as the type of the final \
-                                 field in a struct",
-                                 token::get_ident(ident)).as_slice());
+                    span_err!(tcx.sess, f.span, E0042,
+                        "type `{}` is dynamically sized. \
+                         dynamically sized types may only \
+                         appear as the type of the final \
+                         field in a struct",
+                        token::get_ident(ident));
                 }
                 ast::UnnamedField(_) => {
-                    tcx.sess.span_err(f.span, "dynamically sized type in field");
+                    span_err!(tcx.sess, f.span, E0043,
+                        "dynamically sized type in field");
                 }
             }
         }
@@ -719,14 +718,15 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
             for item in m.items.iter() {
                 let pty = ty::lookup_item_type(ccx.tcx, local_def(item.id));
                 if !pty.generics.types.is_empty() {
-                    ccx.tcx.sess.span_err(item.span, "foreign items may not have type parameters");
+                    span_err!(ccx.tcx.sess, item.span, E0044,
+                        "foreign items may not have type parameters");
                 }
 
                 match item.node {
                     ast::ForeignItemFn(ref fn_decl, _) => {
                         if fn_decl.variadic && m.abi != abi::C {
-                            ccx.tcx.sess.span_err(
-                                item.span, "variadic function must have C calling convention");
+                            span_err!(ccx.tcx.sess, item.span, E0045,
+                                "variadic function must have C calling convention");
                         }
                     }
                     _ => {}
@@ -826,10 +826,9 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
     }
 
     if !missing_methods.is_empty() {
-        tcx.sess.span_err(
-            impl_span,
-            format!("not all trait methods implemented, missing: {}",
-                    missing_methods.connect(", ")).as_slice());
+        span_err!(tcx.sess, impl_span, E0046,
+            "not all trait methods implemented, missing: {}",
+            missing_methods.connect(", "));
     }
 }
 
@@ -865,23 +864,17 @@ fn compare_impl_method(tcx: &ty::ctxt,
     match (&trait_m.explicit_self, &impl_m.explicit_self) {
         (&ast::SelfStatic, &ast::SelfStatic) => {}
         (&ast::SelfStatic, _) => {
-            tcx.sess.span_err(
-                impl_m_span,
-                format!("method `{}` has a `{}` declaration in the impl, \
-                        but not in the trait",
-                        token::get_ident(trait_m.ident),
-                        pprust::explicit_self_to_string(
-                            impl_m.explicit_self)).as_slice());
+            span_err!(tcx.sess, impl_m_span, E0047,
+                "method `{}` has a `{}` declaration in the impl, but not in the trait",
+                token::get_ident(trait_m.ident),
+                pprust::explicit_self_to_string(impl_m.explicit_self));
             return;
         }
         (_, &ast::SelfStatic) => {
-            tcx.sess.span_err(
-                impl_m_span,
-                format!("method `{}` has a `{}` declaration in the trait, \
-                        but not in the impl",
-                        token::get_ident(trait_m.ident),
-                        pprust::explicit_self_to_string(
-                            trait_m.explicit_self)).as_slice());
+            span_err!(tcx.sess, impl_m_span, E0048,
+                "method `{}` has a `{}` declaration in the trait, but not in the impl",
+                token::get_ident(trait_m.ident),
+                pprust::explicit_self_to_string(trait_m.explicit_self));
             return;
         }
         _ => {
@@ -892,28 +885,26 @@ fn compare_impl_method(tcx: &ty::ctxt,
     let num_impl_m_type_params = impl_m.generics.types.len(subst::FnSpace);
     let num_trait_m_type_params = trait_m.generics.types.len(subst::FnSpace);
     if num_impl_m_type_params != num_trait_m_type_params {
-        tcx.sess.span_err(
-            impl_m_span,
-            format!("method `{}` has {} type parameter{} \
-                     but its trait declaration has {} type parameter{}",
-                    token::get_ident(trait_m.ident),
-                    num_impl_m_type_params,
-                    if num_impl_m_type_params == 1 {""} else {"s"},
-                    num_trait_m_type_params,
-                    if num_trait_m_type_params == 1 {""} else {"s"}).as_slice());
+        span_err!(tcx.sess, impl_m_span, E0049,
+            "method `{}` has {} type parameter{} \
+             but its trait declaration has {} type parameter{}",
+            token::get_ident(trait_m.ident),
+            num_impl_m_type_params,
+            if num_impl_m_type_params == 1 {""} else {"s"},
+            num_trait_m_type_params,
+            if num_trait_m_type_params == 1 {""} else {"s"});
         return;
     }
 
     if impl_m.fty.sig.inputs.len() != trait_m.fty.sig.inputs.len() {
-        tcx.sess.span_err(
-            impl_m_span,
-            format!("method `{}` has {} parameter{} \
-                     but the declaration in trait `{}` has {}",
-                 token::get_ident(trait_m.ident),
-                 impl_m.fty.sig.inputs.len(),
-                 if impl_m.fty.sig.inputs.len() == 1 {""} else {"s"},
-                 ty::item_path_str(tcx, trait_m.def_id),
-                 trait_m.fty.sig.inputs.len()).as_slice());
+        span_err!(tcx.sess, impl_m_span, E0050,
+            "method `{}` has {} parameter{} \
+             but the declaration in trait `{}` has {}",
+            token::get_ident(trait_m.ident),
+            impl_m.fty.sig.inputs.len(),
+            if impl_m.fty.sig.inputs.len() == 1 {""} else {"s"},
+            ty::item_path_str(tcx, trait_m.def_id),
+            trait_m.fty.sig.inputs.len());
         return;
     }
 
@@ -1002,16 +993,13 @@ fn compare_impl_method(tcx: &ty::ctxt,
             impl_param_def.bounds.builtin_bounds -
             trait_param_def.bounds.builtin_bounds;
         if !extra_bounds.is_empty() {
-           tcx.sess.span_err(
-               impl_m_span,
-               format!("in method `{}`, \
-                       type parameter {} requires `{}`, \
-                       which is not required by \
-                       the corresponding type parameter \
-                       in the trait declaration",
-                       token::get_ident(trait_m.ident),
-                       i,
-                       extra_bounds.user_string(tcx)).as_slice());
+            span_err!(tcx.sess, impl_m_span, E0051,
+                "in method `{}`, type parameter {} requires `{}`, \
+                 which is not required by the corresponding type parameter \
+                 in the trait declaration",
+                token::get_ident(trait_m.ident),
+                i,
+                extra_bounds.user_string(tcx));
            return;
         }
 
@@ -1043,17 +1031,12 @@ fn compare_impl_method(tcx: &ty::ctxt,
             }
 
             if !ok {
-                tcx.sess.span_err(impl_m_span,
-                                  format!("in method `{}`, type parameter {} \
-                                           requires bound `{}`, which is not \
-                                           required by the corresponding \
-                                           type parameter in the trait \
-                                           declaration",
-                                          token::get_ident(trait_m.ident),
-                                          i,
-                                          ppaux::trait_ref_to_string(
-                                              tcx,
-                                              &*impl_trait_bound)).as_slice())
+                span_err!(tcx.sess, impl_m_span, E0052,
+                    "in method `{}`, type parameter {} requires bound `{}`, which is not \
+                     required by the corresponding type parameter in the trait declaration",
+                    token::get_ident(trait_m.ident),
+                    i,
+                    ppaux::trait_ref_to_string(tcx, &*impl_trait_bound));
             }
         }
     }
@@ -1071,11 +1054,10 @@ fn compare_impl_method(tcx: &ty::ctxt,
                           impl_fty, trait_fty) {
         Ok(()) => {}
         Err(ref terr) => {
-            tcx.sess.span_err(
-                impl_m_span,
-                format!("method `{}` has an incompatible type for trait: {}",
-                        token::get_ident(trait_m.ident),
-                        ty::type_err_to_str(tcx, terr)).as_slice());
+            span_err!(tcx.sess, impl_m_span, E0053,
+                "method `{}` has an incompatible type for trait: {}",
+                token::get_ident(trait_m.ident),
+                ty::type_err_to_str(tcx, terr));
             ty::note_and_explain_type_err(tcx, terr);
         }
     }
@@ -1162,10 +1144,8 @@ fn check_cast(fcx: &FnCtxt,
             }, t_e, None);
         }
     } else if ty::get(t_1).sty == ty::ty_bool {
-        fcx.tcx()
-           .sess
-           .span_err(span,
-                     "cannot cast as `bool`, compare with zero instead");
+        span_err!(fcx.tcx().sess, span, E0054,
+            "cannot cast as `bool`, compare with zero instead");
     } else if ty::type_is_region_ptr(t_e) && ty::type_is_unsafe_ptr(t_1) {
         fn types_compatible(fcx: &FnCtxt, sp: Span,
                             t1: ty::t, t2: ty::t) -> bool {
@@ -1533,9 +1513,9 @@ pub fn autoderef<T>(fcx: &FnCtxt, sp: Span, base_ty: ty::t,
     }
 
     // We've reached the recursion limit, error gracefully.
-    fcx.tcx().sess.span_err(sp,
-        format!("reached the recursion limit while auto-dereferencing {}",
-                base_ty.repr(fcx.tcx())).as_slice());
+    span_err!(fcx.tcx().sess, sp, E0055,
+        "reached the recursion limit while auto-dereferencing {}",
+        base_ty.repr(fcx.tcx()));
     (ty::mk_err(), 0, None)
 }
 
@@ -1581,11 +1561,11 @@ fn try_overloaded_call(fcx: &FnCtxt,
         write_call(fcx, call_expression, output_type);
 
         if !fcx.tcx().sess.features.overloaded_calls.get() {
-            fcx.tcx().sess.span_err(call_expression.span,
-                                    "overloaded calls are experimental");
-            fcx.tcx().sess.span_note(call_expression.span,
-                                     "add `#[feature(overloaded_calls)]` to \
-                                      the crate attributes to enable");
+            span_err!(fcx.tcx().sess, call_expression.span, E0056,
+                "overloaded calls are experimental");
+            span_note!(fcx.tcx().sess, call_expression.span,
+                "add `#[feature(overloaded_calls)]` to \
+                the crate attributes to enable");
         }
 
         return true
@@ -1783,14 +1763,12 @@ fn check_argument_types(fcx: &FnCtxt,
         match ty::get(tuple_type).sty {
             ty::ty_tup(ref arg_types) => {
                 if arg_types.len() != args.len() {
-                    let msg = format!(
-                        "this function takes {} parameter{} \
-                         but {} parameter{} supplied",
-                         arg_types.len(),
-                         if arg_types.len() == 1 {""} else {"s"},
-                         args.len(),
-                         if args.len() == 1 {" was"} else {"s were"});
-                    tcx.sess.span_err(sp, msg.as_slice());
+                    span_err!(tcx.sess, sp, E0057,
+                        "this function takes {} parameter{} but {} parameter{} supplied",
+                        arg_types.len(),
+                        if arg_types.len() == 1 {""} else {"s"},
+                        args.len(),
+                        if args.len() == 1 {" was"} else {"s were"});
                     err_args(args.len())
                 } else {
                     (*arg_types).clone()
@@ -1798,21 +1776,17 @@ fn check_argument_types(fcx: &FnCtxt,
             }
             ty::ty_nil => {
                 if args.len() != 0 {
-                    let msg = format!(
-                        "this function takes 0 parameters \
-                         but {} parameter{} supplied",
-                         args.len(),
-                         if args.len() == 1 {" was"} else {"s were"});
-                    tcx.sess.span_err(sp, msg.as_slice());
+                    span_err!(tcx.sess, sp, E0058,
+                        "this function takes 0 parameters but {} parameter{} supplied",
+                        args.len(),
+                        if args.len() == 1 {" was"} else {"s were"});
                 }
                 Vec::new()
             }
             _ => {
-                tcx.sess
-                   .span_err(sp,
-                             "cannot use call notation; the first type \
-                              parameter for the function trait is neither a \
-                              tuple nor unit");
+                span_err!(tcx.sess, sp, E0059,
+                    "cannot use call notation; the first type parameter \
+                     for the function trait is neither a tuple nor unit");
                 err_args(supplied_arg_count)
             }
         }
@@ -1822,29 +1796,22 @@ fn check_argument_types(fcx: &FnCtxt,
         if supplied_arg_count >= expected_arg_count {
             fn_inputs.iter().map(|a| *a).collect()
         } else {
-            let msg = format!(
+            span_err!(tcx.sess, sp, E0060,
                 "this function takes at least {} parameter{} \
                  but {} parameter{} supplied",
-                 expected_arg_count,
-                 if expected_arg_count == 1 {""} else {"s"},
-                 supplied_arg_count,
-                 if supplied_arg_count == 1 {" was"} else {"s were"});
-
-            tcx.sess.span_err(sp, msg.as_slice());
-
+                expected_arg_count,
+                if expected_arg_count == 1 {""} else {"s"},
+                supplied_arg_count,
+                if supplied_arg_count == 1 {" was"} else {"s were"});
             err_args(supplied_arg_count)
         }
     } else {
-        let msg = format!(
-            "this function takes {} parameter{} \
-             but {} parameter{} supplied",
-             expected_arg_count,
-             if expected_arg_count == 1 {""} else {"s"},
-             supplied_arg_count,
-             if supplied_arg_count == 1 {" was"} else {"s were"});
-
-        tcx.sess.span_err(sp, msg.as_slice());
-
+        span_err!(tcx.sess, sp, E0061,
+            "this function takes {} parameter{} but {} parameter{} supplied",
+            expected_arg_count,
+            if expected_arg_count == 1 {""} else {"s"},
+            supplied_arg_count,
+            if supplied_arg_count == 1 {" was"} else {"s were"});
         err_args(supplied_arg_count)
     };
 
@@ -2730,11 +2697,9 @@ fn check_struct_or_variant_fields(fcx: &FnCtxt,
                     error_happened = true;
                 }
                 Some((_, true)) => {
-                    tcx.sess.span_err(
-                        field.ident.span,
-                        format!("field `{}` specified more than once",
-                                token::get_ident(field.ident
-                                                      .node)).as_slice());
+                    span_err!(fcx.tcx().sess, field.ident.span, E0062,
+                        "field `{}` specified more than once",
+                        token::get_ident(field.ident.node));
                     error_happened = true;
                 }
                 Some((field_id, false)) => {
@@ -2772,11 +2737,10 @@ fn check_struct_or_variant_fields(fcx: &FnCtxt,
                     }
                 }
 
-                tcx.sess.span_err(span,
-                    format!(
-                        "missing field{}: {fields}",
-                        if missing_fields.len() == 1 {""} else {"s"},
-                        fields = missing_fields.connect(", ")).as_slice());
+                span_err!(tcx.sess, span, E0063,
+                    "missing field{}: {}",
+                    if missing_fields.len() == 1 {""} else {"s"},
+                    missing_fields.connect(", "));
              }
         }
 
@@ -2938,12 +2902,14 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
                     }
                 }
                 ast::ExprLit(_) => {
-                    let error = if vst == ast::ExprVstoreSlice {
-                        "`&\"string\"` has been removed; use `\"string\"` instead"
+                    if vst == ast::ExprVstoreSlice {
+                        span_err!(tcx.sess, expr.span, E0064,
+                            "`&\"string\"` has been removed; use `\"string\"` instead");
                     } else {
-                        "`box \"string\"` has been removed; use `\"string\".to_string()` instead"
-                    };
-                    tcx.sess.span_err(expr.span, error);
+                        span_err!(tcx.sess, expr.span, E0065,
+                            "`box \"string\"` has been removed; use \
+                             `\"string\".to_string()` instead");
+                    }
                     ty::mk_err()
                 }
                 _ => tcx.sess.span_bug(expr.span, "vstore modifier on non-sequence"),
@@ -2977,9 +2943,8 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
           }
 
           if !checked {
-              tcx.sess.span_err(expr.span,
-                                "only the managed heap and exchange heap are \
-                                 currently supported");
+              span_err!(tcx.sess, expr.span, E0066,
+                  "only the managed heap and exchange heap are currently supported");
               fcx.write_ty(id, ty::mk_err());
           }
       }
@@ -3011,7 +2976,7 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
 
         let tcx = fcx.tcx();
         if !ty::expr_is_lval(tcx, &**lhs) {
-            tcx.sess.span_err(lhs.span, "illegal left-hand side expression");
+            span_err!(tcx.sess, lhs.span, E0067, "illegal left-hand side expression");
         }
 
         // Overwrite result of check_binop...this preserves existing behavior
@@ -3077,7 +3042,7 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
                                 };
                                 if is_newtype {
                                     // This is an obsolete struct deref
-                                    tcx.sess.span_err(expr.span,
+                                    span_err!(tcx.sess, expr.span, E0068,
                                         "single-field tuple-structs can \
                                          no longer be dereferenced");
                                 } else {
@@ -3181,8 +3146,7 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
                                     ret_ty, ty::mk_nil()) {
             Ok(_) => { /* fall through */ }
             Err(_) => {
-                tcx.sess.span_err(
-                    expr.span,
+                span_err!(tcx.sess, expr.span, E0069,
                     "`return;` in function returning non-nil");
             }
           },
@@ -3201,7 +3165,8 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
 
         let tcx = fcx.tcx();
         if !ty::expr_is_lval(tcx, &**lhs) {
-            tcx.sess.span_err(lhs.span, "illegal left-hand side expression");
+            span_err!(tcx.sess, expr.span, E0070,
+                "illegal left-hand side expression");
         }
 
         let lhs_ty = fcx.expr_ty(&**lhs);
@@ -3390,11 +3355,9 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
                                                  base_expr);
                     }
                     _ => {
-                        tcx.sess
-                           .span_err(path.span,
-                                     format!("`{}` does not name a structure",
-                                             pprust::path_to_string(
-                                                 path)).as_slice())
+                        span_err!(tcx.sess, path.span, E0071,
+                            "`{}` does not name a structure",
+                            pprust::path_to_string(path));
                     }
                 }
             }
@@ -3766,10 +3729,10 @@ pub fn check_representable(tcx: &ty::ctxt,
     // caught by case 1.
     match ty::is_type_representable(tcx, sp, rty) {
       ty::SelfRecursive => {
-        tcx.sess.span_err(
-          sp, format!("illegal recursive {} type; \
-                       wrap the inner value in a box to make it representable",
-                      designation).as_slice());
+        span_err!(tcx.sess, sp, E0072,
+            "illegal recursive {} type; \
+             wrap the inner value in a box to make it representable",
+            designation);
         return false
       }
       ty::Representable | ty::ContainsRecursive => (),
@@ -3794,12 +3757,10 @@ pub fn check_instantiable(tcx: &ty::ctxt,
                           -> bool {
     let item_ty = ty::node_id_to_type(tcx, item_id);
     if !ty::is_instantiable(tcx, item_ty) {
-        tcx.sess
-           .span_err(sp,
-                     format!("this type cannot be instantiated without an \
-                              instance of itself; consider using \
-                              `Option<{}>`",
-                             ppaux::ty_to_string(tcx, item_ty)).as_slice());
+        span_err!(tcx.sess, sp, E0073,
+            "this type cannot be instantiated without an \
+             instance of itself; consider using `Option<{}>`",
+            ppaux::ty_to_string(tcx, item_ty));
         false
     } else {
         true
@@ -3809,25 +3770,25 @@ pub fn check_instantiable(tcx: &ty::ctxt,
 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
     let t = ty::node_id_to_type(tcx, id);
     if ty::type_needs_subst(t) {
-        tcx.sess.span_err(sp, "SIMD vector cannot be generic");
+        span_err!(tcx.sess, sp, E0074, "SIMD vector cannot be generic");
         return;
     }
     match ty::get(t).sty {
         ty::ty_struct(did, ref substs) => {
             let fields = ty::lookup_struct_fields(tcx, did);
             if fields.is_empty() {
-                tcx.sess.span_err(sp, "SIMD vector cannot be empty");
+                span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
                 return;
             }
             let e = ty::lookup_field_type(tcx, did, fields.get(0).id, substs);
             if !fields.iter().all(
                          |f| ty::lookup_field_type(tcx, did, f.id, substs) == e) {
-                tcx.sess.span_err(sp, "SIMD vector should be homogeneous");
+                span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
                 return;
             }
             if !ty::type_is_machine(e) {
-                tcx.sess.span_err(sp, "SIMD vector element type should be \
-                                       machine type");
+                span_err!(tcx.sess, sp, E0077,
+                    "SIMD vector element type should be machine type");
                 return;
             }
         }
@@ -3852,16 +3813,10 @@ pub fn check_enum_variants_sized(ccx: &CrateCtxt,
                     // A struct value with an unsized final field is itself
                     // unsized and we must track this in the type system.
                     if !ty::type_is_sized(ccx.tcx, *t) {
-                        ccx.tcx
-                           .sess
-                           .span_err(
-                               args.get(i).ty.span,
-                               format!("type `{}` is dynamically sized. \
-                                        dynamically sized types may only \
-                                        appear as the final type in a \
-                                        variant",
-                                       ppaux::ty_to_string(ccx.tcx,
-                                                        *t)).as_slice());
+                        span_err!(ccx.tcx.sess, args.get(i).ty.span, E0078,
+                            "type `{}` is dynamically sized. dynamically sized types may only \
+                             appear as the final type in a variant",
+                             ppaux::ty_to_string(ccx.tcx, *t));
                     }
                 }
             },
@@ -3947,14 +3902,12 @@ fn do_check(ccx: &CrateCtxt,
                         Ok(const_eval::const_int(val)) => current_disr_val = val as Disr,
                         Ok(const_eval::const_uint(val)) => current_disr_val = val as Disr,
                         Ok(_) => {
-                            ccx.tcx.sess.span_err(e.span, "expected signed integer constant");
+                            span_err!(ccx.tcx.sess, e.span, E0079,
+                                "expected signed integer constant");
                         }
                         Err(ref err) => {
-                            ccx.tcx
-                               .sess
-                               .span_err(e.span,
-                                         format!("expected constant: {}",
-                                                 *err).as_slice());
+                            span_err!(ccx.tcx.sess, e.span, E0080,
+                                "expected constant: {}", *err);
                         }
                     }
                 },
@@ -3963,16 +3916,18 @@ fn do_check(ccx: &CrateCtxt,
 
             // Check for duplicate discriminant values
             if disr_vals.contains(&current_disr_val) {
-                ccx.tcx.sess.span_err(v.span, "discriminant value already exists");
+                span_err!(ccx.tcx.sess, v.span, E0081,
+                    "discriminant value already exists");
             }
             // Check for unrepresentable discriminant values
             match hint {
                 attr::ReprAny | attr::ReprExtern => (),
                 attr::ReprInt(sp, ity) => {
                     if !disr_in_range(ccx, ity, current_disr_val) {
-                        ccx.tcx.sess.span_err(v.span,
-                                              "discriminant value outside specified type");
-                        ccx.tcx.sess.span_note(sp, "discriminant type specified here");
+                        span_err!(ccx.tcx.sess, v.span, E0082,
+                            "discriminant value outside specified type");
+                        span_note!(ccx.tcx.sess, sp,
+                            "discriminant type specified here");
                     }
                 }
             }
@@ -3990,12 +3945,13 @@ fn do_check(ccx: &CrateCtxt,
 
     let hint = ty::lookup_repr_hint(ccx.tcx, ast::DefId { krate: ast::LOCAL_CRATE, node: id });
     if hint != attr::ReprAny && vs.len() <= 1 {
-        let msg = if vs.len() == 1 {
-            "unsupported representation for univariant enum"
+        if vs.len() == 1 {
+            span_err!(ccx.tcx.sess, sp, E0083,
+                "unsupported representation for univariant enum");
         } else {
-            "unsupported representation for zero-variant enum"
+            span_err!(ccx.tcx.sess, sp, E0084,
+                "unsupported representation for zero-variant enum");
         };
-        ccx.tcx.sess.span_err(sp, msg)
     }
 
     let variants = do_check(ccx, vs, id, hint);
@@ -4241,15 +4197,13 @@ fn report_error_if_segment_contains_type_parameters(
         segment: &ast::PathSegment)
     {
         for typ in segment.types.iter() {
-            fcx.tcx().sess.span_err(
-                typ.span,
+            span_err!(fcx.tcx().sess, typ.span, E0085,
                 "type parameters may not appear here");
             break;
         }
 
         for lifetime in segment.lifetimes.iter() {
-            fcx.tcx().sess.span_err(
-                lifetime.span,
+            span_err!(fcx.tcx().sess, lifetime.span, E0086,
                 "lifetime parameters may not appear here");
             break;
         }
@@ -4288,14 +4242,11 @@ fn push_explicit_parameters_from_segment_to_substs(
                 if i < type_count {
                     substs.types.push(space, t);
                 } else if i == type_count {
-                    fcx.tcx().sess.span_err(
-                        typ.span,
-                        format!(
-                            "too many type parameters provided: \
-                             expected at most {} parameter(s) \
-                             but found {} parameter(s)",
-                            type_count,
-                            segment.types.len()).as_slice());
+                    span_err!(fcx.tcx().sess, typ.span, E0087,
+                        "too many type parameters provided: \
+                         expected at most {} parameter(s) \
+                         but found {} parameter(s)",
+                         type_count, segment.types.len());
                     substs.types.truncate(space, 0);
                 }
             }
@@ -4309,13 +4260,11 @@ fn push_explicit_parameters_from_segment_to_substs(
                 if i < region_count {
                     substs.mut_regions().push(space, r);
                 } else if i == region_count {
-                    fcx.tcx().sess.span_err(
-                        lifetime.span,
-                        format!(
-                            "too many lifetime parameters provided: \
-                             expected {} parameter(s) but found {} parameter(s)",
-                            region_count,
-                            segment.lifetimes.len()).as_slice());
+                    span_err!(fcx.tcx().sess, lifetime.span, E0088,
+                        "too many lifetime parameters provided: \
+                         expected {} parameter(s) but found {} parameter(s)",
+                        region_count,
+                        segment.lifetimes.len());
                     substs.mut_regions().truncate(space, 0);
                 }
             }
@@ -4360,14 +4309,10 @@ fn adjust_type_parameters(
         if provided_len < required_len {
             let qualifier =
                 if desired.len() != required_len { "at least " } else { "" };
-            fcx.tcx().sess.span_err(
-                span,
-                format!("too few type parameters provided: \
-                             expected {}{} parameter(s) \
-                             but found {} parameter(s)",
-                            qualifier,
-                            required_len,
-                            provided_len).as_slice());
+            span_err!(fcx.tcx().sess, span, E0089,
+                "too few type parameters provided: expected {}{} parameter(s) \
+                 but found {} parameter(s)",
+                qualifier, required_len, provided_len);
             substs.types.replace(space,
                                  Vec::from_elem(desired.len(), ty::mk_err()));
             return;
@@ -4418,14 +4363,10 @@ fn adjust_region_parameters(
 
         // Otherwise, too few were provided. Report an error and then
         // use inference variables.
-        fcx.tcx().sess.span_err(
-            span,
-            format!(
-                "too few lifetime parameters provided: \
-                         expected {} parameter(s) \
-                         but found {} parameter(s)",
-                desired.len(),
-                provided_len).as_slice());
+        span_err!(fcx.tcx().sess, span, E0090,
+            "too few lifetime parameters provided: expected {} parameter(s) \
+             but found {} parameter(s)",
+            desired.len(), provided_len);
 
         substs.mut_regions().replace(
             space,
@@ -4547,10 +4488,9 @@ pub fn check_bounds_are_used(ccx: &CrateCtxt,
 
     for (i, b) in tps_used.iter().enumerate() {
         if !*b {
-            ccx.tcx.sess.span_err(
-                span,
-                format!("type parameter `{}` is unused",
-                        token::get_ident(tps.get(i).ident)).as_slice());
+            span_err!(ccx.tcx.sess, span, E0091,
+                "type parameter `{}` is unused",
+                token::get_ident(tps.get(i).ident));
         }
     }
 }
@@ -4586,10 +4526,8 @@ fn param(ccx: &CrateCtxt, n: uint) -> ty::t {
                 (0, Vec::new(), ty::mk_nil())
             }
             op => {
-                tcx.sess.span_err(it.span,
-                                  format!("unrecognized atomic operation \
-                                           function: `{}`",
-                                          op).as_slice());
+                span_err!(tcx.sess, it.span, E0092,
+                    "unrecognized atomic operation function: `{}`", op);
                 return;
             }
         }
@@ -4813,9 +4751,8 @@ fn param(ccx: &CrateCtxt, n: uint) -> ty::t {
                 ty::mk_tup(tcx, vec!(ty::mk_u64(), ty::mk_bool()))),
 
             ref other => {
-                tcx.sess.span_err(it.span,
-                                  format!("unrecognized intrinsic function: `{}`",
-                                          *other).as_slice());
+                span_err!(tcx.sess, it.span, E0093,
+                    "unrecognized intrinsic function: `{}`", *other);
                 return;
             }
         }
@@ -4833,11 +4770,10 @@ fn param(ccx: &CrateCtxt, n: uint) -> ty::t {
     let i_ty = ty::lookup_item_type(ccx.tcx, local_def(it.id));
     let i_n_tps = i_ty.generics.types.len(subst::FnSpace);
     if i_n_tps != n_tps {
-        tcx.sess.span_err(it.span,
-                          format!("intrinsic has wrong number of type \
-                                   parameters: found {}, expected {}",
-                                  i_n_tps,
-                                  n_tps).as_slice());
+        span_err!(tcx.sess, it.span, E0094,
+            "intrinsic has wrong number of type \
+             parameters: found {}, expected {}",
+             i_n_tps, n_tps);
     } else {
         require_same_types(tcx,
                            None,
index 9bb5eae2ed2d66c893378ee316e419c01e53f90b..0b26a641f8d508ccc78edd2c1b3a62ade133c9d3 100644 (file)
@@ -98,6 +98,9 @@ pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
     pub fn span_warn(&self, sp: Span, msg: &str) {
         self.handler.emit(Some((&self.cm, sp)), msg, Warning);
     }
+    pub fn span_warn_with_code(&self, sp: Span, msg: &str, code: &str) {
+        self.handler.emit_with_code(Some((&self.cm, sp)), msg, code, Warning);
+    }
     pub fn span_note(&self, sp: Span, msg: &str) {
         self.handler.emit(Some((&self.cm, sp)), msg, Note);
     }
index b0260e1180f8f89b655e59749b758b0ef3d63dfe..b4af7205c42068fae0ea49c8ec5f5427887bf85b 100644 (file)
@@ -49,3 +49,25 @@ macro_rules! span_err(
         ($session).span_err_with_code($span, format!($($arg),*).as_slice(), stringify!($code))
     })
 )
+
+#[macro_export]
+macro_rules! span_warn(
+    ($session:expr, $span:expr, $code:ident, $($arg:expr),*) => ({
+        __diagnostic_used!($code);
+        ($session).span_warn_with_code($span, format!($($arg),*).as_slice(), stringify!($code))
+    })
+)
+
+#[macro_export]
+macro_rules! span_note(
+    ($session:expr, $span:expr, $($arg:expr),*) => ({
+        ($session).span_note($span, format!($($arg),*).as_slice())
+    })
+)
+
+#[macro_export]
+macro_rules! register_diagnostics(
+    ($($code:tt),*) => (
+        $(register_diagnostic!($code))*
+    )
+)
index 6582d2e44c8e391c3f0e4b9c43a1d431931210dd..209296989fa0de1e12d0fdecb3f257f8f7fe0f03 100644 (file)
@@ -54,7 +54,8 @@ pub fn expand_diagnostic_used(ecx: &mut ExtCtxt, span: Span,
     with_registered_diagnostics(|diagnostics| {
         if !diagnostics.contains_key(&code.name) {
             ecx.span_err(span, format!(
-                "unknown diagnostic code {}", token::get_ident(code).get()
+                "unknown diagnostic code {}; add to librustc/diagnostics.rs",
+                token::get_ident(code).get()
             ).as_slice());
         }
         ()