]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #30457 - Manishearth:rollup, r=Manishearth
authorbors <bors@rust-lang.org>
Fri, 18 Dec 2015 15:17:29 +0000 (15:17 +0000)
committerbors <bors@rust-lang.org>
Fri, 18 Dec 2015 15:17:29 +0000 (15:17 +0000)
- Successful merges: #30272, #30286, #30365, #30381, #30384, #30398, #30406, #30408, #30420, #30431, #30447, #30452
- Failed merges:

76 files changed:
src/doc/book/macros.md
src/doc/book/patterns.md
src/librustc/lint/context.rs
src/librustc/middle/check_match.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/infer/error_reporting.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/stability.rs
src/librustc/middle/ty/structural_impls.rs
src/librustc/session/config.rs
src/librustc/session/mod.rs
src/librustc/session/search_paths.rs
src/librustc_back/target/mod.rs
src/librustc_driver/lib.rs
src/librustc_driver/test.rs
src/librustc_front/fold.rs
src/librustc_front/hir.rs
src/librustc_front/lib.rs
src/librustc_front/lowering.rs
src/librustc_front/print/pprust.rs
src/librustc_front/util.rs
src/librustc_llvm/lib.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/loader.rs
src/librustc_metadata/tyencode.rs
src/librustc_mir/hair/cx/pattern.rs
src/librustc_plugin/build.rs
src/librustc_trans/back/lto.rs
src/librustc_trans/back/write.rs
src/librustc_trans/save/dump_csv.rs
src/librustc_trans/trans/adt.rs
src/librustc_trans/trans/callee.rs
src/librustc_trans/trans/consts.rs
src/librustc_trans/trans/monomorphize.rs
src/librustc_typeck/check/mod.rs
src/librustdoc/clean/mod.rs
src/librustdoc/core.rs
src/librustdoc/doctree.rs
src/librustdoc/lib.rs
src/librustdoc/test.rs
src/librustdoc/visit_ast.rs
src/libstd/rand/os.rs
src/libsyntax/ast.rs
src/libsyntax/ast_util.rs
src/libsyntax/attr.rs
src/libsyntax/config.rs
src/libsyntax/diagnostic.rs [deleted file]
src/libsyntax/errors/emitter.rs [new file with mode: 0644]
src/libsyntax/errors/mod.rs [new file with mode: 0644]
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/tt/transcribe.rs
src/libsyntax/feature_gate.rs
src/libsyntax/fold.rs
src/libsyntax/lib.rs
src/libsyntax/owned_slice.rs
src/libsyntax/parse/lexer/comments.rs
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/obsolete.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/ptr.rs
src/libsyntax/show_span.rs
src/libsyntax/test.rs
src/libsyntax/util/move_map.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/libsyntax_ext/deriving/generic/ty.rs
src/libsyntax_ext/lib.rs
src/test/run-make/emit/Makefile [new file with mode: 0644]
src/test/run-make/emit/test-24876.rs [new file with mode: 0644]
src/test/run-make/emit/test-26235.rs [new file with mode: 0644]
src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs
src/test/run-pass-fulldeps/compiler-calls.rs

index f7f27858cd24042a5342ca292da7b93b331223d4..e4a900a2b1a4f8c79b9d7e538460d64680d4878e 100644 (file)
@@ -485,10 +485,10 @@ These rules provide some flexibility for Rust’s syntax to evolve without
 breaking existing macros.
 
 The macro system does not deal with parse ambiguity at all. For example, the
-grammar `$($t:ty)* $e:expr` will always fail to parse, because the parser would
-be forced to choose between parsing `$t` and parsing `$e`. Changing the
+grammar `$($i:ident)* $e:expr` will always fail to parse, because the parser would
+be forced to choose between parsing `$i` and parsing `$e`. Changing the
 invocation syntax to put a distinctive token in front can solve the problem. In
-this case, you can write `$(T $t:ty)* E $e:exp`.
+this case, you can write `$(I $i:ident)* E $e:expr`.
 
 [item]: ../reference.html#items
 
index 8f4a7a439553b8d4cf7f52ea7c4c42f50905fee0..43f1bd2529fd2c85e7455f1e7cdfeaa233c56f04 100644 (file)
@@ -27,7 +27,7 @@ There’s one pitfall with patterns: like anything that introduces a new binding
 they introduce shadowing. For example:
 
 ```rust
-let x = 'x';
+let x = 1;
 let c = 'c';
 
 match c {
@@ -41,12 +41,14 @@ This prints:
 
 ```text
 x: c c: c
-x: x
+x: 1
 ```
 
 In other words, `x =>` matches the pattern and introduces a new binding named
-`x` that’s in scope for the match arm. Because we already have a binding named
-`x`, this new `x` shadows it.
+`x`. This new binding is in scope for the match arm and takes on the value of
+`c`. Notice that the value of `x` outside the scope of the match has no bearing
+on the value of `x` within it. Because we already have a binding named `x`, this
+new `x` shadows it.
 
 # Multiple patterns
 
index d7ac096b4073576b65e0f50c31a470c7c8db3c5d..db22000fd9f5d1b5080315b0324aa61c2ab04579 100644 (file)
@@ -47,7 +47,7 @@
 use rustc_front::util;
 use rustc_front::intravisit as hir_visit;
 use syntax::visit as ast_visit;
-use syntax::diagnostic;
+use syntax::errors;
 
 /// Information about the registered lints.
 ///
@@ -167,7 +167,7 @@ fn push_pass<P: LintPass + ?Sized + 'static>(&mut self,
                 match (sess, from_plugin) {
                     // We load builtin lints first, so a duplicate is a compiler bug.
                     // Use early_error when handling -W help with no crate.
-                    (None, _) => early_error(diagnostic::Auto, &msg[..]),
+                    (None, _) => early_error(errors::ColorConfig::Auto, &msg[..]),
                     (Some(sess), false) => sess.bug(&msg[..]),
 
                     // A duplicate name from a plugin is a user error.
@@ -191,7 +191,7 @@ pub fn register_group(&mut self, sess: Option<&Session>,
             match (sess, from_plugin) {
                 // We load builtin lints first, so a duplicate is a compiler bug.
                 // Use early_error when handling -W help with no crate.
-                (None, _) => early_error(diagnostic::Auto, &msg[..]),
+                (None, _) => early_error(errors::ColorConfig::Auto, &msg[..]),
                 (Some(sess), false) => sess.bug(&msg[..]),
 
                 // A duplicate name from a plugin is a user error.
index ba4bdccb20b805583d50c4eaa19adc45fac2067c..cab7e45ee62832522f99b664a1d4b3f269967ff7 100644 (file)
@@ -517,7 +517,7 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
         ty::TyEnum(adt, _) | ty::TyStruct(adt, _)  => {
             let v = adt.variant_of_ctor(ctor);
             if let VariantKind::Struct = v.kind() {
-                let field_pats: Vec<_> = v.fields.iter()
+                let field_pats: hir::HirVec<_> = v.fields.iter()
                     .zip(pats)
                     .filter(|&(_, ref pat)| pat.node != hir::PatWild)
                     .map(|(field, pat)| Spanned {
@@ -540,14 +540,14 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
                ty::TyArray(_, n) => match ctor {
                     &Single => {
                         assert_eq!(pats_len, n);
-                        hir::PatVec(pats.collect(), None, vec!())
+                        hir::PatVec(pats.collect(), None, hir::HirVec::new())
                     },
                     _ => unreachable!()
                 },
                 ty::TySlice(_) => match ctor {
                     &Slice(n) => {
                         assert_eq!(pats_len, n);
-                        hir::PatVec(pats.collect(), None, vec!())
+                        hir::PatVec(pats.collect(), None, hir::HirVec::new())
                     },
                     _ => unreachable!()
                 },
@@ -562,7 +562,7 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
 
         ty::TyArray(_, len) => {
             assert_eq!(pats_len, len);
-            hir::PatVec(pats.collect(), None, vec![])
+            hir::PatVec(pats.collect(), None, hir::HirVec::new())
         }
 
         _ => {
index 974231be0edf88c9cdc660b3f36f53a4d15fe85a..54061a14d1419644ff1880c9849dbdf5a433f63b 100644 (file)
@@ -357,14 +357,14 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<hir::Pat>
 
         hir::ExprVec(ref exprs) => {
             let pats = exprs.iter().map(|expr| const_expr_to_pat(tcx, &**expr, span)).collect();
-            hir::PatVec(pats, None, vec![])
+            hir::PatVec(pats, None, hir::HirVec::new())
         }
 
         hir::ExprPath(_, ref path) => {
             let opt_def = tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def());
             match opt_def {
                 Some(def::DefStruct(..)) =>
-                    hir::PatStruct(path.clone(), vec![], false),
+                    hir::PatStruct(path.clone(), hir::HirVec::new(), false),
                 Some(def::DefVariant(..)) =>
                     hir::PatEnum(path.clone(), None),
                 _ => {
index 4861f0a6b643641aa8d5ed13b29242732480a4fe..73776304bc846d65cec3a38d1dc0a8a9326e25c7 100644 (file)
@@ -324,7 +324,7 @@ fn delegate_consume(&mut self,
         self.delegate.consume(consume_id, consume_span, cmt, mode);
     }
 
-    fn consume_exprs(&mut self, exprs: &Vec<P<hir::Expr>>) {
+    fn consume_exprs(&mut self, exprs: &[P<hir::Expr>]) {
         for expr in exprs {
             self.consume_expr(&**expr);
         }
@@ -651,7 +651,7 @@ fn walk_block(&mut self, blk: &hir::Block) {
 
     fn walk_struct_expr(&mut self,
                         _expr: &hir::Expr,
-                        fields: &Vec<hir::Field>,
+                        fields: &[hir::Field],
                         opt_with: &Option<P<hir::Expr>>) {
         // Consume the expressions supplying values for each field.
         for field in fields {
@@ -697,7 +697,7 @@ fn walk_struct_expr(&mut self,
         self.walk_expr(with_expr);
 
         fn contains_field_named(field: ty::FieldDef,
-                                fields: &Vec<hir::Field>)
+                                fields: &[hir::Field])
                                 -> bool
         {
             fields.iter().any(
index e894878e43ce1fecd7445e523e3475bc76a0ed99..2abf499185690f7c8bd9ef3f251946637cb095f4 100644 (file)
@@ -90,7 +90,6 @@
 use std::char::from_u32;
 use std::fmt;
 use syntax::ast;
-use syntax::owned_slice::OwnedSlice;
 use syntax::codemap::{self, Pos, Span};
 use syntax::parse::token;
 use syntax::ptr::P;
@@ -1154,10 +1153,10 @@ fn track_anon(&self, anon: u32) {
     }
 
     fn rebuild_ty_params(&self,
-                         ty_params: OwnedSlice<hir::TyParam>,
+                         ty_params: P<[hir::TyParam]>,
                          lifetime: hir::Lifetime,
                          region_names: &HashSet<ast::Name>)
-                         -> OwnedSlice<hir::TyParam> {
+                         -> P<[hir::TyParam]> {
         ty_params.map(|ty_param| {
             let bounds = self.rebuild_ty_param_bounds(ty_param.bounds.clone(),
                                                       lifetime,
@@ -1173,10 +1172,10 @@ fn rebuild_ty_params(&self,
     }
 
     fn rebuild_ty_param_bounds(&self,
-                               ty_param_bounds: OwnedSlice<hir::TyParamBound>,
+                               ty_param_bounds: hir::TyParamBounds,
                                lifetime: hir::Lifetime,
                                region_names: &HashSet<ast::Name>)
-                               -> OwnedSlice<hir::TyParamBound> {
+                               -> hir::TyParamBounds {
         ty_param_bounds.map(|tpb| {
             match tpb {
                 &hir::RegionTyParamBound(lt) => {
@@ -1249,13 +1248,13 @@ fn rebuild_generics(&self,
                         add: &Vec<hir::Lifetime>,
                         keep: &HashSet<ast::Name>,
                         remove: &HashSet<ast::Name>,
-                        ty_params: OwnedSlice<hir::TyParam>,
+                        ty_params: P<[hir::TyParam]>,
                         where_clause: hir::WhereClause)
                         -> hir::Generics {
         let mut lifetimes = Vec::new();
         for lt in add {
             lifetimes.push(hir::LifetimeDef { lifetime: *lt,
-                                              bounds: Vec::new() });
+                                              bounds: hir::HirVec::new() });
         }
         for lt in &generics.lifetimes {
             if keep.contains(&lt.lifetime.name) ||
@@ -1264,7 +1263,7 @@ fn rebuild_generics(&self,
             }
         }
         hir::Generics {
-            lifetimes: lifetimes,
+            lifetimes: lifetimes.into(),
             ty_params: ty_params,
             where_clause: where_clause,
         }
@@ -1275,7 +1274,7 @@ fn rebuild_args_ty(&self,
                        lifetime: hir::Lifetime,
                        anon_nums: &HashSet<u32>,
                        region_names: &HashSet<ast::Name>)
-                       -> Vec<hir::Arg> {
+                       -> hir::HirVec<hir::Arg> {
         let mut new_inputs = Vec::new();
         for arg in inputs {
             let new_ty = self.rebuild_arg_ty_or_output(&*arg.ty, lifetime,
@@ -1287,7 +1286,7 @@ fn rebuild_args_ty(&self,
             };
             new_inputs.push(possibly_new_arg);
         }
-        new_inputs
+        new_inputs.into()
     }
 
     fn rebuild_output(&self, ty: &hir::FunctionRetTy,
@@ -1514,7 +1513,7 @@ fn rebuild_path(&self,
                     }
                 });
                 hir::AngleBracketedParameters(hir::AngleBracketedParameterData {
-                    lifetimes: new_lts,
+                    lifetimes: new_lts.into(),
                     types: new_types,
                     bindings: new_bindings,
                })
@@ -1530,7 +1529,7 @@ fn rebuild_path(&self,
         hir::Path {
             span: path.span,
             global: path.global,
-            segments: new_segs
+            segments: new_segs.into()
         }
     }
 }
index 89fa76f2fa769d5b9f181fc44b1bd0ba0324abe9..9b133c5401519f595ff08dbe9a6f86bc99e89ecd 100644 (file)
@@ -79,10 +79,10 @@ struct LifetimeContext<'a> {
 enum ScopeChain<'a> {
     /// EarlyScope(i, ['a, 'b, ...], s) extends s with early-bound
     /// lifetimes, assigning indexes 'a => i, 'b => i+1, ... etc.
-    EarlyScope(subst::ParamSpace, &'a Vec<hir::LifetimeDef>, Scope<'a>),
+    EarlyScope(subst::ParamSpace, &'a [hir::LifetimeDef], Scope<'a>),
     /// LateScope(['a, 'b, ...], s) extends s with late-bound
     /// lifetimes introduced by the declaration binder_id.
-    LateScope(&'a Vec<hir::LifetimeDef>, Scope<'a>),
+    LateScope(&'a [hir::LifetimeDef], Scope<'a>),
 
     /// lifetimes introduced by a fn are scoped to the call-site for that fn.
     FnScope { fn_id: ast::NodeId, body_id: ast::NodeId, s: Scope<'a> },
@@ -206,7 +206,7 @@ fn visit_ty(&mut self, ty: &hir::Ty) {
                 // a trait ref, which introduces a binding scope.
                 match self.def_map.get(&ty.id).map(|d| (d.base_def, d.depth)) {
                     Some((def::DefTrait(..), 0)) => {
-                        self.with(LateScope(&Vec::new(), self.scope), |_, this| {
+                        self.with(LateScope(&[], self.scope), |_, this| {
                             this.visit_path(path, ty.id);
                         });
                     }
@@ -661,7 +661,7 @@ fn unresolved_lifetime_ref(&self, lifetime_ref: &hir::Lifetime) {
                     lifetime_ref.name);
     }
 
-    fn check_lifetime_defs(&mut self, old_scope: Scope, lifetimes: &Vec<hir::LifetimeDef>) {
+    fn check_lifetime_defs(&mut self, old_scope: Scope, lifetimes: &[hir::LifetimeDef]) {
         for i in 0..lifetimes.len() {
             let lifetime_i = &lifetimes[i];
 
@@ -753,7 +753,7 @@ fn insert_lifetime(&mut self,
     }
 }
 
-fn search_lifetimes<'a>(lifetimes: &'a Vec<hir::LifetimeDef>,
+fn search_lifetimes<'a>(lifetimes: &'a [hir::LifetimeDef],
                     lifetime_ref: &hir::Lifetime)
                     -> Option<(u32, &'a hir::Lifetime)> {
     for (i, lifetime_decl) in lifetimes.iter().enumerate() {
index 8104d53fc936fed71708bd660d9632ba9be55ced..a41ee51fb5546023991fd29f56b2f53a0b190806 100644 (file)
@@ -82,7 +82,7 @@ struct Annotator<'a, 'tcx: 'a> {
 impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
     // Determine the stability for a node based on its attributes and inherited
     // stability. The stability is recorded in the index and used as the parent.
-    fn annotate<F>(&mut self, id: NodeId, attrs: &Vec<Attribute>,
+    fn annotate<F>(&mut self, id: NodeId, attrs: &[Attribute],
                    item_sp: Span, kind: AnnotationKind, visit_children: F)
         where F: FnOnce(&mut Annotator)
     {
index e6007809af5e90e9a218cfd60f385c5619c9b82a..ecb2b85fd77445c98fea253e61f4404dc4aaeb88 100644 (file)
@@ -16,7 +16,7 @@
 
 use std::rc::Rc;
 use syntax::abi;
-use syntax::owned_slice::OwnedSlice;
+use syntax::ptr::P;
 
 use rustc_front::hir;
 
@@ -555,8 +555,8 @@ fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::Binder<T> {
     }
 }
 
-impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for OwnedSlice<T> {
-    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> OwnedSlice<T> {
+impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for P<[T]> {
+    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> P<[T]> {
         self.iter().map(|t| t.fold_with(folder)).collect()
     }
 }
index 6fb8c03370142713f7c935fee8a1765e53af2a0b..e33fe9570c024f9bfaac483a1da7c47776a4834b 100644 (file)
@@ -27,7 +27,7 @@
 use syntax::ast::{self, IntTy, UintTy};
 use syntax::attr;
 use syntax::attr::AttrMetaMethods;
-use syntax::diagnostic::{ColorConfig, Auto, Always, Never, SpanHandler};
+use syntax::errors::{ColorConfig, Handler};
 use syntax::parse;
 use syntax::parse::token::InternedString;
 use syntax::feature_gate::UnstableFeatures;
@@ -238,7 +238,7 @@ pub fn basic_options() -> Options {
         debugging_opts: basic_debugging_options(),
         prints: Vec::new(),
         cg: basic_codegen_options(),
-        color: Auto,
+        color: ColorConfig::Auto,
         show_span: None,
         externs: HashMap::new(),
         crate_name: None,
@@ -687,19 +687,19 @@ pub fn build_configuration(sess: &Session) -> ast::CrateConfig {
     v
 }
 
-pub fn build_target_config(opts: &Options, sp: &SpanHandler) -> Config {
+pub fn build_target_config(opts: &Options, sp: &Handler) -> Config {
     let target = match Target::search(&opts.target_triple) {
         Ok(t) => t,
         Err(e) => {
-            panic!(sp.handler().fatal(&format!("Error loading target specification: {}", e)));
+            panic!(sp.fatal(&format!("Error loading target specification: {}", e)));
         }
     };
 
     let (int_type, uint_type) = match &target.target_pointer_width[..] {
         "32" => (ast::TyI32, ast::TyU32),
         "64" => (ast::TyI64, ast::TyU64),
-        w    => panic!(sp.handler().fatal(&format!("target specification was invalid: \
-                                                    unrecognized target-pointer-width {}", w))),
+        w    => panic!(sp.fatal(&format!("target specification was invalid: \
+                                          unrecognized target-pointer-width {}", w))),
     };
 
     Config {
@@ -884,16 +884,16 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String> ) -> ast::CrateConfig {
 
 pub fn build_session_options(matches: &getopts::Matches) -> Options {
     let color = match matches.opt_str("color").as_ref().map(|s| &s[..]) {
-        Some("auto")   => Auto,
-        Some("always") => Always,
-        Some("never")  => Never,
+        Some("auto")   => ColorConfig::Auto,
+        Some("always") => ColorConfig::Always,
+        Some("never")  => ColorConfig::Never,
 
-        None => Auto,
+        None => ColorConfig::Auto,
 
         Some(arg) => {
-            early_error(Auto, &format!("argument for --color must be auto, always \
-                                        or never (instead was `{}`)",
-                                       arg))
+            early_error(ColorConfig::Auto, &format!("argument for --color must be auto, always \
+                                                     or never (instead was `{}`)",
+                                                    arg))
         }
     };
 
@@ -1224,7 +1224,7 @@ fn test_can_print_warnings() {
             let sessopts = build_session_options(&matches);
             let sess = build_session(sessopts, None, registry,
                                      Rc::new(DummyCrateStore));
-            assert!(!sess.can_print_warnings);
+            assert!(!sess.diagnostic().can_emit_warnings);
         }
 
         {
@@ -1236,7 +1236,7 @@ fn test_can_print_warnings() {
             let sessopts = build_session_options(&matches);
             let sess = build_session(sessopts, None, registry,
                                      Rc::new(DummyCrateStore));
-            assert!(sess.can_print_warnings);
+            assert!(sess.diagnostic().can_emit_warnings);
         }
 
         {
@@ -1247,7 +1247,7 @@ fn test_can_print_warnings() {
             let sessopts = build_session_options(&matches);
             let sess = build_session(sessopts, None, registry,
                                      Rc::new(DummyCrateStore));
-            assert!(sess.can_print_warnings);
+            assert!(sess.diagnostic().can_emit_warnings);
         }
     }
 }
index b7bfc2f8db53ecc4569c2b63cde8f22cab34bda1..7b96db4bf0a3af87e3283dc5cd672b30c5303865 100644 (file)
@@ -16,7 +16,8 @@
 
 use syntax::ast::{NodeId, NodeIdAssigner, Name};
 use syntax::codemap::Span;
-use syntax::diagnostic::{self, Emitter};
+use syntax::errors;
+use syntax::errors::emitter::{Emitter, BasicEmitter};
 use syntax::diagnostics;
 use syntax::feature_gate;
 use syntax::parse;
@@ -63,14 +64,10 @@ pub struct Session {
     pub crate_metadata: RefCell<Vec<String>>,
     pub features: RefCell<feature_gate::Features>,
 
-    pub delayed_span_bug: RefCell<Option<(codemap::Span, String)>>,
-
     /// The maximum recursion limit for potentially infinitely recursive
     /// operations such as auto-dereference and monomorphization.
     pub recursion_limit: Cell<usize>,
 
-    pub can_print_warnings: bool,
-
     /// The metadata::creader module may inject an allocator dependency if it
     /// didn't already find one, and this tracks what was injected.
     pub injected_allocator: Cell<Option<ast::CrateNum>>,
@@ -84,22 +81,13 @@ pub struct Session {
 
 impl Session {
     pub fn span_fatal(&self, sp: Span, msg: &str) -> ! {
-        if self.opts.treat_err_as_bug {
-            self.span_bug(sp, msg);
-        }
         panic!(self.diagnostic().span_fatal(sp, msg))
     }
     pub fn span_fatal_with_code(&self, sp: Span, msg: &str, code: &str) -> ! {
-        if self.opts.treat_err_as_bug {
-            self.span_bug(sp, msg);
-        }
         panic!(self.diagnostic().span_fatal_with_code(sp, msg, code))
     }
     pub fn fatal(&self, msg: &str) -> ! {
-        if self.opts.treat_err_as_bug {
-            self.bug(msg);
-        }
-        panic!(self.diagnostic().handler().fatal(msg))
+        panic!(self.diagnostic().fatal(msg))
     }
     pub fn span_err_or_warn(&self, is_warning: bool, sp: Span, msg: &str) {
         if is_warning {
@@ -109,9 +97,6 @@ pub fn span_err_or_warn(&self, is_warning: bool, sp: Span, msg: &str) {
         }
     }
     pub fn span_err(&self, sp: Span, msg: &str) {
-        if self.opts.treat_err_as_bug {
-            self.span_bug(sp, msg);
-        }
         match split_msg_into_multilines(msg) {
             Some(msg) => self.diagnostic().span_err(sp, &msg[..]),
             None => self.diagnostic().span_err(sp, msg)
@@ -125,36 +110,22 @@ pub fn note_rfc_1214(&self, span: Span) {
                       See RFC 1214 for details."));
     }
     pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
-        if self.opts.treat_err_as_bug {
-            self.span_bug(sp, msg);
-        }
         match split_msg_into_multilines(msg) {
             Some(msg) => self.diagnostic().span_err_with_code(sp, &msg[..], code),
             None => self.diagnostic().span_err_with_code(sp, msg, code)
         }
     }
     pub fn err(&self, msg: &str) {
-        if self.opts.treat_err_as_bug {
-            self.bug(msg);
-        }
-        self.diagnostic().handler().err(msg)
+        self.diagnostic().err(msg)
     }
     pub fn err_count(&self) -> usize {
-        self.diagnostic().handler().err_count()
+        self.diagnostic().err_count()
     }
     pub fn has_errors(&self) -> bool {
-        self.diagnostic().handler().has_errors()
+        self.diagnostic().has_errors()
     }
     pub fn abort_if_errors(&self) {
-        self.diagnostic().handler().abort_if_errors();
-
-        let delayed_bug = self.delayed_span_bug.borrow();
-        match *delayed_bug {
-            Some((span, ref errmsg)) => {
-                self.diagnostic().span_bug(span, errmsg);
-            },
-            _ => {}
-        }
+        self.diagnostic().abort_if_errors();
     }
     pub fn abort_if_new_errors<F>(&self, mut f: F)
         where F: FnMut()
@@ -166,19 +137,13 @@ pub fn abort_if_new_errors<F>(&self, mut f: F)
         }
     }
     pub fn span_warn(&self, sp: Span, msg: &str) {
-        if self.can_print_warnings {
-            self.diagnostic().span_warn(sp, msg)
-        }
+        self.diagnostic().span_warn(sp, msg)
     }
     pub fn span_warn_with_code(&self, sp: Span, msg: &str, code: &str) {
-        if self.can_print_warnings {
-            self.diagnostic().span_warn_with_code(sp, msg, code)
-        }
+        self.diagnostic().span_warn_with_code(sp, msg, code)
     }
     pub fn warn(&self, msg: &str) {
-        if self.can_print_warnings {
-            self.diagnostic().handler().warn(msg)
-        }
+        self.diagnostic().warn(msg)
     }
     pub fn opt_span_warn(&self, opt_sp: Option<Span>, msg: &str) {
         match opt_sp {
@@ -195,7 +160,7 @@ pub fn span_end_note(&self, sp: Span, msg: &str) {
 
     /// Prints out a message with a suggested edit of the code.
     ///
-    /// See `diagnostic::RenderSpan::Suggestion` for more information.
+    /// See `errors::RenderSpan::Suggestion` for more information.
     pub fn span_suggestion(&self, sp: Span, msg: &str, suggestion: String) {
         self.diagnostic().span_suggestion(sp, msg, suggestion)
     }
@@ -209,10 +174,10 @@ pub fn fileline_help(&self, sp: Span, msg: &str) {
         self.diagnostic().fileline_help(sp, msg)
     }
     pub fn note(&self, msg: &str) {
-        self.diagnostic().handler().note(msg)
+        self.diagnostic().note(msg)
     }
     pub fn help(&self, msg: &str) {
-        self.diagnostic().handler().help(msg)
+        self.diagnostic().help(msg)
     }
     pub fn opt_span_bug(&self, opt_sp: Option<Span>, msg: &str) -> ! {
         match opt_sp {
@@ -222,20 +187,19 @@ pub fn opt_span_bug(&self, opt_sp: Option<Span>, msg: &str) -> ! {
     }
     /// Delay a span_bug() call until abort_if_errors()
     pub fn delay_span_bug(&self, sp: Span, msg: &str) {
-        let mut delayed = self.delayed_span_bug.borrow_mut();
-        *delayed = Some((sp, msg.to_string()));
+        self.diagnostic().delay_span_bug(sp, msg)
     }
     pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
         self.diagnostic().span_bug(sp, msg)
     }
     pub fn bug(&self, msg: &str) -> ! {
-        self.diagnostic().handler().bug(msg)
+        self.diagnostic().bug(msg)
     }
     pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! {
         self.diagnostic().span_unimpl(sp, msg)
     }
     pub fn unimpl(&self, msg: &str) -> ! {
-        self.diagnostic().handler().unimpl(msg)
+        self.diagnostic().unimpl(msg)
     }
     pub fn add_lint(&self,
                     lint: &'static lint::Lint,
@@ -260,7 +224,7 @@ pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId {
 
         id
     }
-    pub fn diagnostic<'a>(&'a self) -> &'a diagnostic::SpanHandler {
+    pub fn diagnostic<'a>(&'a self) -> &'a errors::Handler {
         &self.parse_sess.span_diagnostic
     }
     pub fn codemap<'a>(&'a self) -> &'a codemap::CodeMap {
@@ -269,8 +233,7 @@ pub fn codemap<'a>(&'a self) -> &'a codemap::CodeMap {
     // This exists to help with refactoring to eliminate impossible
     // cases later on
     pub fn impossible_case(&self, sp: Span, msg: &str) -> ! {
-        self.span_bug(sp,
-                      &format!("impossible case reached: {}", msg));
+        self.span_bug(sp, &format!("impossible case reached: {}", msg));
     }
     pub fn verbose(&self) -> bool { self.opts.debugging_opts.verbose }
     pub fn time_passes(&self) -> bool { self.opts.debugging_opts.time_passes }
@@ -413,30 +376,33 @@ pub fn build_session(sopts: config::Options,
         .map(|&(_, ref level)| *level != lint::Allow)
         .last()
         .unwrap_or(true);
+    let treat_err_as_bug = sopts.treat_err_as_bug;
 
-    let codemap = codemap::CodeMap::new();
+    let codemap = Rc::new(codemap::CodeMap::new());
     let diagnostic_handler =
-        diagnostic::Handler::new(sopts.color, Some(registry), can_print_warnings);
-    let span_diagnostic_handler =
-        diagnostic::SpanHandler::new(diagnostic_handler, codemap);
+        errors::Handler::new(sopts.color,
+                             Some(registry),
+                             can_print_warnings,
+                             treat_err_as_bug,
+                             codemap.clone());
 
-    build_session_(sopts, local_crate_source_file, span_diagnostic_handler, cstore)
+    build_session_(sopts, local_crate_source_file, diagnostic_handler, codemap, cstore)
 }
 
 pub fn build_session_(sopts: config::Options,
                       local_crate_source_file: Option<PathBuf>,
-                      span_diagnostic: diagnostic::SpanHandler,
+                      span_diagnostic: errors::Handler,
+                      codemap: Rc<codemap::CodeMap>,
                       cstore: Rc<for<'a> CrateStore<'a>>)
                       -> Session {
     let host = match Target::search(config::host_triple()) {
         Ok(t) => t,
         Err(e) => {
-            panic!(span_diagnostic.handler()
-                                  .fatal(&format!("Error loading host specification: {}", e)));
+            panic!(span_diagnostic.fatal(&format!("Error loading host specification: {}", e)));
     }
     };
     let target_cfg = config::build_target_config(&sopts, &span_diagnostic);
-    let p_s = parse::ParseSess::with_span_handler(span_diagnostic);
+    let p_s = parse::ParseSess::with_span_handler(span_diagnostic, codemap);
     let default_sysroot = match sopts.maybe_sysroot {
         Some(_) => None,
         None => Some(filesearch::get_or_default_sysroot())
@@ -451,13 +417,6 @@ pub fn build_session_(sopts: config::Options,
         }
     );
 
-    let can_print_warnings = sopts.lint_opts
-        .iter()
-        .filter(|&&(ref key, _)| *key == "warnings")
-        .map(|&(_, ref level)| *level != lint::Allow)
-        .last()
-        .unwrap_or(true);
-
     let sess = Session {
         target: target_cfg,
         host: host,
@@ -478,10 +437,8 @@ pub fn build_session_(sopts: config::Options,
         crate_types: RefCell::new(Vec::new()),
         dependency_formats: RefCell::new(FnvHashMap()),
         crate_metadata: RefCell::new(Vec::new()),
-        delayed_span_bug: RefCell::new(None),
         features: RefCell::new(feature_gate::Features::new()),
         recursion_limit: Cell::new(64),
-        can_print_warnings: can_print_warnings,
         next_node_id: Cell::new(1),
         injected_allocator: Cell::new(None),
         available_macros: RefCell::new(HashSet::new()),
@@ -490,20 +447,13 @@ pub fn build_session_(sopts: config::Options,
     sess
 }
 
-// Seems out of place, but it uses session, so I'm putting it here
-pub fn expect<T, M>(sess: &Session, opt: Option<T>, msg: M) -> T where
-    M: FnOnce() -> String,
-{
-    diagnostic::expect(sess.diagnostic(), opt, msg)
-}
-
-pub fn early_error(color: diagnostic::ColorConfig, msg: &str) -> ! {
-    let mut emitter = diagnostic::EmitterWriter::stderr(color, None);
-    emitter.emit(None, msg, None, diagnostic::Fatal);
-    panic!(diagnostic::FatalError);
+pub fn early_error(color: errors::ColorConfig, msg: &str) -> ! {
+    let mut emitter = BasicEmitter::stderr(color);
+    emitter.emit(None, msg, None, errors::Level::Fatal);
+    panic!(errors::FatalError);
 }
 
-pub fn early_warn(color: diagnostic::ColorConfig, msg: &str) {
-    let mut emitter = diagnostic::EmitterWriter::stderr(color, None);
-    emitter.emit(None, msg, None, diagnostic::Warning);
+pub fn early_warn(color: errors::ColorConfig, msg: &str) {
+    let mut emitter = BasicEmitter::stderr(color);
+    emitter.emit(None, msg, None, errors::Level::Warning);
 }
index caf776dad85e06ff28ebda7ee9a77b19dbb4b680..6a787139d77aa88c3d96dfa981da7f41c9fbdfde 100644 (file)
@@ -11,7 +11,7 @@
 use std::slice;
 use std::path::{Path, PathBuf};
 use session::early_error;
-use syntax::diagnostic;
+use syntax::errors;
 
 #[derive(Clone, Debug)]
 pub struct SearchPaths {
@@ -38,7 +38,7 @@ pub fn new() -> SearchPaths {
         SearchPaths { paths: Vec::new() }
     }
 
-    pub fn add_path(&mut self, path: &str, color: diagnostic::ColorConfig) {
+    pub fn add_path(&mut self, path: &str, color: errors::ColorConfig) {
         let (kind, path) = if path.starts_with("native=") {
             (PathKind::Native, &path["native=".len()..])
         } else if path.starts_with("crate=") {
index 1bfb7471daa212b580c75cdfb9790afce158fb5d..f259698a220e2be8022a92de7bc1fae45b0b3be7 100644 (file)
@@ -48,7 +48,7 @@
 use serialize::json::Json;
 use std::default::Default;
 use std::io::prelude::*;
-use syntax::{diagnostic, abi};
+use syntax::abi;
 
 mod android_base;
 mod apple_base;
@@ -263,17 +263,13 @@ pub fn adjust_abi(&self, abi: abi::Abi) -> abi::Abi {
     pub fn from_json(obj: Json) -> Target {
         // this is 1. ugly, 2. error prone.
 
-
-        let handler = diagnostic::Handler::new(diagnostic::Auto, None, true);
-
         let get_req_field = |name: &str| {
             match obj.find(name)
                      .map(|s| s.as_string())
                      .and_then(|os| os.map(|s| s.to_string())) {
                 Some(val) => val,
                 None => {
-                    panic!(handler.fatal(&format!("Field {} in target specification is required",
-                                                  name)))
+                    panic!("Field {} in target specification is required", name)
                 }
             }
         };
index fcbcdbacd33cb7e753ded519fb3c7b1e0639e6f9..8cfaec62f47754cacf5cc2eea895ca647b68f125 100644 (file)
@@ -59,8 +59,6 @@
 extern crate syntax;
 extern crate syntax_ext;
 
-pub use syntax::diagnostic;
-
 use driver::CompileController;
 use pretty::{PpMode, UserIdentifiedItem};
 
@@ -91,7 +89,8 @@
 
 use syntax::ast;
 use syntax::parse;
-use syntax::diagnostic::Emitter;
+use syntax::errors;
+use syntax::errors::emitter::Emitter;
 use syntax::diagnostics;
 use syntax::parse::token;
 
@@ -239,7 +238,7 @@ pub trait CompilerCalls<'a> {
     fn early_callback(&mut self,
                       _: &getopts::Matches,
                       _: &diagnostics::registry::Registry,
-                      _: diagnostic::ColorConfig)
+                      _: errors::ColorConfig)
                       -> Compilation {
         Compilation::Continue
     }
@@ -315,7 +314,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
     fn early_callback(&mut self,
                       matches: &getopts::Matches,
                       descriptions: &diagnostics::registry::Registry,
-                      color: diagnostic::ColorConfig)
+                      color: errors::ColorConfig)
                       -> Compilation {
         match matches.opt_str("explain") {
             Some(ref code) => {
@@ -774,7 +773,7 @@ fn parse_all_options(args: &Vec<String>) -> getopts::Matches {
                             &opt.opt_group.short_name
                         };
                         if m.opt_present(opt_name) {
-                            early_error(diagnostic::Auto,
+                            early_error(errors::ColorConfig::Auto,
                                         &format!("use of unstable option '{}' requires -Z \
                                                   unstable-options",
                                                  opt_name));
@@ -783,7 +782,7 @@ fn parse_all_options(args: &Vec<String>) -> getopts::Matches {
                 }
                 m
             }
-            Err(f) => early_error(diagnostic::Auto, &f.to_string()),
+            Err(f) => early_error(errors::ColorConfig::Auto, &f.to_string()),
         }
     }
 
@@ -895,25 +894,25 @@ fn flush(&mut self) -> io::Result<()> {
         }
         Err(value) => {
             // Thread panicked without emitting a fatal diagnostic
-            if !value.is::<diagnostic::FatalError>() {
-                let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
+            if !value.is::<errors::FatalError>() {
+                let mut emitter = errors::emitter::BasicEmitter::stderr(errors::ColorConfig::Auto);
 
                 // a .span_bug or .bug call has already printed what
                 // it wants to print.
-                if !value.is::<diagnostic::ExplicitBug>() {
-                    emitter.emit(None, "unexpected panic", None, diagnostic::Bug);
+                if !value.is::<errors::ExplicitBug>() {
+                    emitter.emit(None, "unexpected panic", None, errors::Level::Bug);
                 }
 
                 let xs = ["the compiler unexpectedly panicked. this is a bug.".to_string(),
                           format!("we would appreciate a bug report: {}", BUG_REPORT_URL)];
                 for note in &xs {
-                    emitter.emit(None, &note[..], None, diagnostic::Note)
+                    emitter.emit(None, &note[..], None, errors::Level::Note)
                 }
                 if let None = env::var_os("RUST_BACKTRACE") {
                     emitter.emit(None,
                                  "run with `RUST_BACKTRACE=1` for a backtrace",
                                  None,
-                                 diagnostic::Note);
+                                 errors::Level::Note);
                 }
 
                 println!("{}", str::from_utf8(&data.lock().unwrap()).unwrap());
index 2fb23c943c76a3fe327376b2369d50efa3974424..df9294a9d5bfb518cbcab55efb94e6b909154294 100644 (file)
@@ -10,8 +10,6 @@
 
 //! # Standalone Tests for the Inference Module
 
-use diagnostic;
-use diagnostic::Emitter;
 use driver;
 use rustc_lint;
 use rustc_resolve as resolve;
 use rustc::session::{self, config};
 use std::rc::Rc;
 use syntax::{abi, ast};
-use syntax::codemap;
 use syntax::codemap::{Span, CodeMap, DUMMY_SP};
-use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note, Help};
+use syntax::errors;
+use syntax::errors::emitter::Emitter;
+use syntax::errors::{Level, RenderSpan};
 use syntax::parse::token;
 use syntax::feature_gate::UnstableFeatures;
 
@@ -60,8 +59,8 @@ struct ExpectErrorEmitter {
 
 fn remove_message(e: &mut ExpectErrorEmitter, msg: &str, lvl: Level) {
     match lvl {
-        Bug | Fatal | Error => {}
-        Warning | Note | Help => {
+        Level::Bug | Level::Fatal | Level::Error => {}
+        Level::Warning | Level::Note | Level::Help => {
             return;
         }
     }
@@ -79,14 +78,14 @@ fn remove_message(e: &mut ExpectErrorEmitter, msg: &str, lvl: Level) {
 
 impl Emitter for ExpectErrorEmitter {
     fn emit(&mut self,
-            _cmsp: Option<(&codemap::CodeMap, Span)>,
+            _sp: Option<Span>,
             msg: &str,
             _: Option<&str>,
             lvl: Level) {
         remove_message(self, msg, lvl);
     }
 
-    fn custom_emit(&mut self, _cm: &codemap::CodeMap, _sp: RenderSpan, msg: &str, lvl: Level) {
+    fn custom_emit(&mut self, _sp: RenderSpan, msg: &str, lvl: Level) {
         remove_message(self, msg, lvl);
     }
 }
@@ -105,13 +104,11 @@ fn test_env<F>(source_string: &str,
     let mut options = config::basic_options();
     options.debugging_opts.verbose = true;
     options.unstable_features = UnstableFeatures::Allow;
-    let codemap = CodeMap::new();
-    let diagnostic_handler = diagnostic::Handler::with_emitter(true, emitter);
-    let span_diagnostic_handler = diagnostic::SpanHandler::new(diagnostic_handler, codemap);
+    let diagnostic_handler = errors::Handler::with_emitter(true, false, emitter);
 
     let cstore = Rc::new(CStore::new(token::get_ident_interner()));
-    let sess = session::build_session_(options, None, span_diagnostic_handler,
-                                       cstore.clone());
+    let sess = session::build_session_(options, None, diagnostic_handler,
+                                       Rc::new(CodeMap::new()), cstore.clone());
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
     let krate_config = Vec::new();
     let input = config::Input::Str(source_string.to_string());
@@ -366,13 +363,6 @@ pub fn glb(&self) -> Glb<'a, 'tcx> {
         self.infcx.glb(true, trace)
     }
 
-    pub fn make_lub_ty(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> Ty<'tcx> {
-        match self.lub().relate(&t1, &t2) {
-            Ok(t) => t,
-            Err(ref e) => panic!("unexpected error computing LUB: {}", e),
-        }
-    }
-
     /// Checks that `t1 <: t2` is true (this may register additional
     /// region checks).
     pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
index 88a34b27c31897ed7eefce630dee12376a035bee..784428cc114dc0cd9e7dba13dd0dd4e416aac3df 100644 (file)
@@ -17,7 +17,6 @@
 use syntax::attr::ThinAttributesExt;
 use hir;
 use syntax::codemap::{respan, Span, Spanned};
-use syntax::owned_slice::OwnedSlice;
 use syntax::ptr::P;
 use syntax::parse::token;
 use syntax::util::move_map::MoveMap;
@@ -35,7 +34,7 @@ fn fold_crate(&mut self, c: Crate) -> Crate {
         noop_fold_crate(c, self)
     }
 
-    fn fold_meta_items(&mut self, meta_items: Vec<P<MetaItem>>) -> Vec<P<MetaItem>> {
+    fn fold_meta_items(&mut self, meta_items: HirVec<P<MetaItem>>) -> HirVec<P<MetaItem>> {
         noop_fold_meta_items(meta_items, self)
     }
 
@@ -199,11 +198,11 @@ fn fold_variant_data(&mut self, vdata: VariantData) -> VariantData {
         noop_fold_variant_data(vdata, self)
     }
 
-    fn fold_lifetimes(&mut self, lts: Vec<Lifetime>) -> Vec<Lifetime> {
+    fn fold_lifetimes(&mut self, lts: HirVec<Lifetime>) -> HirVec<Lifetime> {
         noop_fold_lifetimes(lts, self)
     }
 
-    fn fold_lifetime_defs(&mut self, lts: Vec<LifetimeDef>) -> Vec<LifetimeDef> {
+    fn fold_lifetime_defs(&mut self, lts: HirVec<LifetimeDef>) -> HirVec<LifetimeDef> {
         noop_fold_lifetime_defs(lts, self)
     }
 
@@ -211,7 +210,7 @@ fn fold_ty_param(&mut self, tp: TyParam) -> TyParam {
         noop_fold_ty_param(tp, self)
     }
 
-    fn fold_ty_params(&mut self, tps: OwnedSlice<TyParam>) -> OwnedSlice<TyParam> {
+    fn fold_ty_params(&mut self, tps: P<[TyParam]>) -> P<[TyParam]> {
         noop_fold_ty_params(tps, self)
     }
 
@@ -220,12 +219,12 @@ fn fold_opt_lifetime(&mut self, o_lt: Option<Lifetime>) -> Option<Lifetime> {
     }
 
     fn fold_opt_bounds(&mut self,
-                       b: Option<OwnedSlice<TyParamBound>>)
-                       -> Option<OwnedSlice<TyParamBound>> {
+                       b: Option<TyParamBounds>)
+                       -> Option<TyParamBounds> {
         noop_fold_opt_bounds(b, self)
     }
 
-    fn fold_bounds(&mut self, b: OwnedSlice<TyParamBound>) -> OwnedSlice<TyParamBound> {
+    fn fold_bounds(&mut self, b: TyParamBounds) -> TyParamBounds {
         noop_fold_bounds(b, self)
     }
 
@@ -264,9 +263,9 @@ fn new_span(&mut self, sp: Span) -> Span {
     }
 }
 
-pub fn noop_fold_meta_items<T: Folder>(meta_items: Vec<P<MetaItem>>,
+pub fn noop_fold_meta_items<T: Folder>(meta_items: HirVec<P<MetaItem>>,
                                        fld: &mut T)
-                                       -> Vec<P<MetaItem>> {
+                                       -> HirVec<P<MetaItem>> {
     meta_items.move_map(|x| fld.fold_meta_item(x))
 }
 
@@ -305,7 +304,7 @@ pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<
     })
 }
 
-pub fn fold_attrs<T: Folder>(attrs: Vec<Attribute>, fld: &mut T) -> Vec<Attribute> {
+pub fn fold_attrs<T: Folder>(attrs: HirVec<Attribute>, fld: &mut T) -> HirVec<Attribute> {
     attrs.move_flat_map(|x| fld.fold_attribute(x))
 }
 
@@ -478,7 +477,7 @@ pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> {
             pat: fld.fold_pat(pat),
             init: init.map(|e| fld.fold_expr(e)),
             span: fld.new_span(span),
-            attrs: attrs.map_thin_attrs(|attrs| fold_attrs(attrs, fld)),
+            attrs: attrs.map_thin_attrs(|attrs| fold_attrs(attrs.into(), fld).into()),
         }
     })
 }
@@ -576,9 +575,9 @@ pub fn noop_fold_ty_param<T: Folder>(tp: TyParam, fld: &mut T) -> TyParam {
     }
 }
 
-pub fn noop_fold_ty_params<T: Folder>(tps: OwnedSlice<TyParam>,
+pub fn noop_fold_ty_params<T: Folder>(tps: P<[TyParam]>,
                                       fld: &mut T)
-                                      -> OwnedSlice<TyParam> {
+                                      -> P<[TyParam]> {
     tps.move_map(|tp| fld.fold_ty_param(tp))
 }
 
@@ -597,11 +596,13 @@ pub fn noop_fold_lifetime_def<T: Folder>(l: LifetimeDef, fld: &mut T) -> Lifetim
     }
 }
 
-pub fn noop_fold_lifetimes<T: Folder>(lts: Vec<Lifetime>, fld: &mut T) -> Vec<Lifetime> {
+pub fn noop_fold_lifetimes<T: Folder>(lts: HirVec<Lifetime>, fld: &mut T) -> HirVec<Lifetime> {
     lts.move_map(|l| fld.fold_lifetime(l))
 }
 
-pub fn noop_fold_lifetime_defs<T: Folder>(lts: Vec<LifetimeDef>, fld: &mut T) -> Vec<LifetimeDef> {
+pub fn noop_fold_lifetime_defs<T: Folder>(lts: HirVec<LifetimeDef>,
+                                          fld: &mut T)
+                                          -> HirVec<LifetimeDef> {
     lts.move_map(|l| fld.fold_lifetime_def(l))
 }
 
@@ -726,9 +727,9 @@ pub fn noop_fold_mt<T: Folder>(MutTy { ty, mutbl }: MutTy, folder: &mut T) -> Mu
     }
 }
 
-pub fn noop_fold_opt_bounds<T: Folder>(b: Option<OwnedSlice<TyParamBound>>,
+pub fn noop_fold_opt_bounds<T: Folder>(b: Option<TyParamBounds>,
                                        folder: &mut T)
-                                       -> Option<OwnedSlice<TyParamBound>> {
+                                       -> Option<TyParamBounds> {
     b.map(|bounds| folder.fold_bounds(bounds))
 }
 
@@ -1140,7 +1141,7 @@ pub fn noop_fold_expr<T: Folder>(Expr { id, node, span, attrs }: Expr, folder: &
             }
         },
         span: folder.new_span(span),
-        attrs: attrs.map_thin_attrs(|attrs| fold_attrs(attrs, folder)),
+        attrs: attrs.map_thin_attrs(|attrs| fold_attrs(attrs.into(), folder).into()),
     }
 }
 
index d1cb82dbeccbc76ca0c1f6e4ddf6e686f08ecdbf..6b2664af60ba5cd3bdf998321199b3396bdf68ee 100644 (file)
@@ -40,9 +40,8 @@
 use syntax::codemap::{self, Span, Spanned, DUMMY_SP, ExpnId};
 use syntax::abi::Abi;
 use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect};
-use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, CrateConfig};
+use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
 use syntax::attr::ThinAttributes;
-use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token::InternedString;
 use syntax::ptr::P;
 
 use std::hash::{Hash, Hasher};
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
+/// HIR doesn't commit to a concrete storage type and have its own alias for a vector.
+/// It can be `Vec`, `P<[T]>` or potentially `Box<[T]>`, or some other container with similar
+/// behavior. Unlike AST, HIR is mostly a static structure, so we can use an owned slice instead
+/// of `Vec` to avoid keeping extra capacity.
+pub type HirVec<T> = Vec<T>;
+
+macro_rules! hir_vec {
+    ($elem:expr; $n:expr) => (
+        $crate::hir::HirVec::from(vec![$elem; $n])
+    );
+    ($($x:expr),*) => (
+        $crate::hir::HirVec::from(vec![$($x),*])
+    );
+    ($($x:expr,)*) => (vec![$($x),*])
+}
+
 /// Identifier in HIR
 #[derive(Clone, Copy, Eq)]
 pub struct Ident {
@@ -130,7 +145,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct LifetimeDef {
     pub lifetime: Lifetime,
-    pub bounds: Vec<Lifetime>,
+    pub bounds: HirVec<Lifetime>,
 }
 
 /// A "Path" is essentially Rust's notion of a name; for instance:
@@ -143,7 +158,7 @@ pub struct Path {
     /// module (like paths in an import).
     pub global: bool,
     /// The segments in the path: the things separated by `::`.
-    pub segments: Vec<PathSegment>,
+    pub segments: HirVec<PathSegment>,
 }
 
 impl fmt::Debug for Path {
@@ -192,9 +207,9 @@ pub enum PathParameters {
 impl PathParameters {
     pub fn none() -> PathParameters {
         AngleBracketedParameters(AngleBracketedParameterData {
-            lifetimes: Vec::new(),
-            types: OwnedSlice::empty(),
-            bindings: OwnedSlice::empty(),
+            lifetimes: HirVec::new(),
+            types: P::empty(),
+            bindings: P::empty(),
         })
     }
 
@@ -224,7 +239,7 @@ pub fn has_types(&self) -> bool {
 
     /// Returns the types that the user wrote. Note that these do not necessarily map to the type
     /// parameters in the parenthesized case.
-    pub fn types(&self) -> Vec<&P<Ty>> {
+    pub fn types(&self) -> HirVec<&P<Ty>> {
         match *self {
             AngleBracketedParameters(ref data) => {
                 data.types.iter().collect()
@@ -238,24 +253,24 @@ pub fn types(&self) -> Vec<&P<Ty>> {
         }
     }
 
-    pub fn lifetimes(&self) -> Vec<&Lifetime> {
+    pub fn lifetimes(&self) -> HirVec<&Lifetime> {
         match *self {
             AngleBracketedParameters(ref data) => {
                 data.lifetimes.iter().collect()
             }
             ParenthesizedParameters(_) => {
-                Vec::new()
+                HirVec::new()
             }
         }
     }
 
-    pub fn bindings(&self) -> Vec<&TypeBinding> {
+    pub fn bindings(&self) -> HirVec<&TypeBinding> {
         match *self {
             AngleBracketedParameters(ref data) => {
                 data.bindings.iter().collect()
             }
             ParenthesizedParameters(_) => {
-                Vec::new()
+                HirVec::new()
             }
         }
     }
@@ -265,12 +280,12 @@ pub fn bindings(&self) -> Vec<&TypeBinding> {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct AngleBracketedParameterData {
     /// The lifetime parameters for this path segment.
-    pub lifetimes: Vec<Lifetime>,
+    pub lifetimes: HirVec<Lifetime>,
     /// The type parameters for this path segment, if present.
-    pub types: OwnedSlice<P<Ty>>,
+    pub types: P<[P<Ty>]>,
     /// Bindings (equality constraints) on associated types, if present.
     /// E.g., `Foo<A=Bar>`.
-    pub bindings: OwnedSlice<TypeBinding>,
+    pub bindings: P<[TypeBinding]>,
 }
 
 impl AngleBracketedParameterData {
@@ -286,7 +301,7 @@ pub struct ParenthesizedParameterData {
     pub span: Span,
 
     /// `(A,B)`
-    pub inputs: Vec<P<Ty>>,
+    pub inputs: HirVec<P<Ty>>,
 
     /// `C`
     pub output: Option<P<Ty>>,
@@ -310,7 +325,7 @@ pub enum TraitBoundModifier {
     Maybe,
 }
 
-pub type TyParamBounds = OwnedSlice<TyParamBound>;
+pub type TyParamBounds = P<[TyParamBound]>;
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct TyParam {
@@ -325,8 +340,8 @@ pub struct TyParam {
 /// of a function, enum, trait, etc.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct Generics {
-    pub lifetimes: Vec<LifetimeDef>,
-    pub ty_params: OwnedSlice<TyParam>,
+    pub lifetimes: HirVec<LifetimeDef>,
+    pub ty_params: P<[TyParam]>,
     pub where_clause: WhereClause,
 }
 
@@ -346,7 +361,7 @@ pub fn is_parameterized(&self) -> bool {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct WhereClause {
     pub id: NodeId,
-    pub predicates: Vec<WherePredicate>,
+    pub predicates: HirVec<WherePredicate>,
 }
 
 /// A single predicate in a `where` clause
@@ -365,11 +380,11 @@ pub enum WherePredicate {
 pub struct WhereBoundPredicate {
     pub span: Span,
     /// Any lifetimes from a `for` binding
-    pub bound_lifetimes: Vec<LifetimeDef>,
+    pub bound_lifetimes: HirVec<LifetimeDef>,
     /// The type being bounded
     pub bounded_ty: P<Ty>,
     /// Trait and lifetime bounds (`Clone+Send+'static`)
-    pub bounds: OwnedSlice<TyParamBound>,
+    pub bounds: TyParamBounds,
 }
 
 /// A lifetime predicate, e.g. `'a: 'b+'c`
@@ -377,7 +392,7 @@ pub struct WhereBoundPredicate {
 pub struct WhereRegionPredicate {
     pub span: Span,
     pub lifetime: Lifetime,
-    pub bounds: Vec<Lifetime>,
+    pub bounds: HirVec<Lifetime>,
 }
 
 /// An equality predicate (unsupported), e.g. `T=int`
@@ -389,13 +404,15 @@ pub struct WhereEqPredicate {
     pub ty: P<Ty>,
 }
 
+pub type CrateConfig = HirVec<P<MetaItem>>;
+
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
 pub struct Crate {
     pub module: Mod,
-    pub attrs: Vec<Attribute>,
+    pub attrs: HirVec<Attribute>,
     pub config: CrateConfig,
     pub span: Span,
-    pub exported_macros: Vec<MacroDef>,
+    pub exported_macros: HirVec<MacroDef>,
 
     // NB: We use a BTreeMap here so that `visit_all_items` iterates
     // over the ids in increasing order. In principle it should not
@@ -432,20 +449,20 @@ pub fn visit_all_items<'hir, V:Visitor<'hir>>(&'hir self, visitor: &mut V) {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct MacroDef {
     pub name: Name,
-    pub attrs: Vec<Attribute>,
+    pub attrs: HirVec<Attribute>,
     pub id: NodeId,
     pub span: Span,
     pub imported_from: Option<Name>,
     pub export: bool,
     pub use_locally: bool,
     pub allow_internal_unstable: bool,
-    pub body: Vec<TokenTree>,
+    pub body: HirVec<TokenTree>,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct Block {
     /// Statements in a block
-    pub stmts: Vec<Stmt>,
+    pub stmts: HirVec<Stmt>,
     /// An expression at the end of the block
     /// without a semicolon, if any
     pub expr: Option<P<Expr>>,
@@ -504,7 +521,7 @@ pub enum Pat_ {
     PatIdent(BindingMode, Spanned<Ident>, Option<P<Pat>>),
 
     /// "None" means a `Variant(..)` pattern where we don't bind the fields to names.
-    PatEnum(Path, Option<Vec<P<Pat>>>),
+    PatEnum(Path, Option<HirVec<P<Pat>>>),
 
     /// An associated const named using the qualified path `<T>::CONST` or
     /// `<T as Trait>::CONST`. Associated consts from inherent impls can be
@@ -514,9 +531,9 @@ pub enum Pat_ {
 
     /// Destructuring of a struct, e.g. `Foo {x, y, ..}`
     /// The `bool` is `true` in the presence of a `..`
-    PatStruct(Path, Vec<Spanned<FieldPat>>, bool),
+    PatStruct(Path, HirVec<Spanned<FieldPat>>, bool),
     /// A tuple pattern `(a, b)`
-    PatTup(Vec<P<Pat>>),
+    PatTup(HirVec<P<Pat>>),
     /// A `box` pattern
     PatBox(P<Pat>),
     /// A reference pattern, e.g. `&mut (a, b)`
@@ -527,7 +544,7 @@ pub enum Pat_ {
     PatRange(P<Expr>, P<Expr>),
     /// `[a, b, ..i, y, z]` is represented as:
     ///     `PatVec(box [a, b], Some(i), box [y, z])`
-    PatVec(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
+    PatVec(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>),
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
@@ -641,8 +658,8 @@ pub enum Decl_ {
 /// represents one arm of a 'match'
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct Arm {
-    pub attrs: Vec<Attribute>,
-    pub pats: Vec<P<Pat>>,
+    pub attrs: HirVec<Attribute>,
+    pub pats: HirVec<P<Pat>>,
     pub guard: Option<P<Expr>>,
     pub body: P<Expr>,
 }
@@ -691,12 +708,12 @@ pub enum Expr_ {
     /// A `box x` expression.
     ExprBox(P<Expr>),
     /// An array (`[a, b, c, d]`)
-    ExprVec(Vec<P<Expr>>),
+    ExprVec(HirVec<P<Expr>>),
     /// A function call
     ///
     /// The first field resolves to the function itself,
     /// and the second field is the list of arguments
-    ExprCall(P<Expr>, Vec<P<Expr>>),
+    ExprCall(P<Expr>, HirVec<P<Expr>>),
     /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
     ///
     /// The `Spanned<Name>` is the identifier for the method name.
@@ -709,9 +726,9 @@ pub enum Expr_ {
     ///
     /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
     /// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
-    ExprMethodCall(Spanned<Name>, Vec<P<Ty>>, Vec<P<Expr>>),
+    ExprMethodCall(Spanned<Name>, HirVec<P<Ty>>, HirVec<P<Expr>>),
     /// A tuple (`(a, b, c ,d)`)
-    ExprTup(Vec<P<Expr>>),
+    ExprTup(HirVec<P<Expr>>),
     /// A binary operation (For example: `a + b`, `a * b`)
     ExprBinary(BinOp, P<Expr>, P<Expr>),
     /// A unary operation (For example: `!x`, `*x`)
@@ -734,7 +751,7 @@ pub enum Expr_ {
     ExprLoop(P<Block>, Option<Ident>),
     /// A `match` block, with a source that indicates whether or not it is
     /// the result of a desugaring, and if so, which kind.
-    ExprMatch(P<Expr>, Vec<Arm>, MatchSource),
+    ExprMatch(P<Expr>, HirVec<Arm>, MatchSource),
     /// A closure (for example, `move |a, b, c| {a + b + c}`)
     ExprClosure(CaptureClause, P<FnDecl>, P<Block>),
     /// A block (`{ ... }`)
@@ -761,7 +778,7 @@ pub enum Expr_ {
     /// parameters, e.g. foo::bar::<baz>.
     ///
     /// Optionally "qualified",
-    /// e.g. `<Vec<T> as SomeTrait>::SomeType`.
+    /// e.g. `<HirVec<T> as SomeTrait>::SomeType`.
     ExprPath(Option<QSelf>, Path),
 
     /// A referencing operation (`&a` or `&mut a`)
@@ -780,7 +797,7 @@ pub enum Expr_ {
     ///
     /// For example, `Foo {x: 1, y: 2}`, or
     /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
-    ExprStruct(Path, Vec<Field>, Option<P<Expr>>),
+    ExprStruct(Path, HirVec<Field>, Option<P<Expr>>),
 
     /// A vector literal constructed from one repeated element.
     ///
@@ -794,11 +811,11 @@ pub enum Expr_ {
 /// separately. `position` represents the index of the associated
 /// item qualified with this Self type.
 ///
-///     <Vec<T> as a::b::Trait>::AssociatedItem
+///     <HirVec<T> as a::b::Trait>::AssociatedItem
 ///      ^~~~~     ~~~~~~~~~~~~~~^
 ///      ty        position = 3
 ///
-///     <Vec<T>>::AssociatedItem
+///     <HirVec<T>>::AssociatedItem
 ///      ^~~~~    ^
 ///      ty       position = 0
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
@@ -851,7 +868,7 @@ pub struct MethodSig {
 pub struct TraitItem {
     pub id: NodeId,
     pub name: Name,
-    pub attrs: Vec<Attribute>,
+    pub attrs: HirVec<Attribute>,
     pub node: TraitItem_,
     pub span: Span,
 }
@@ -868,7 +885,7 @@ pub struct ImplItem {
     pub id: NodeId,
     pub name: Name,
     pub vis: Visibility,
-    pub attrs: Vec<Attribute>,
+    pub attrs: HirVec<Attribute>,
     pub node: ImplItemKind,
     pub span: Span,
 }
@@ -919,7 +936,7 @@ pub enum PrimTy {
 pub struct BareFnTy {
     pub unsafety: Unsafety,
     pub abi: Abi,
-    pub lifetimes: Vec<LifetimeDef>,
+    pub lifetimes: HirVec<LifetimeDef>,
     pub decl: P<FnDecl>,
 }
 
@@ -936,9 +953,9 @@ pub enum Ty_ {
     /// A bare function (e.g. `fn(usize) -> bool`)
     TyBareFn(P<BareFnTy>),
     /// A tuple (`(A, B, C, D,...)`)
-    TyTup(Vec<P<Ty>>),
+    TyTup(HirVec<P<Ty>>),
     /// A path (`module::module::...::Type`), optionally
-    /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
+    /// "qualified", e.g. `<HirVec<T> as SomeTrait>::SomeType`.
     ///
     /// Type parameters are stored in the Path itself
     TyPath(Option<QSelf>, Path),
@@ -965,9 +982,9 @@ pub struct InlineAsmOutput {
 pub struct InlineAsm {
     pub asm: InternedString,
     pub asm_str_style: StrStyle,
-    pub outputs: Vec<InlineAsmOutput>,
-    pub inputs: Vec<(InternedString, P<Expr>)>,
-    pub clobbers: Vec<InternedString>,
+    pub outputs: HirVec<InlineAsmOutput>,
+    pub inputs: HirVec<(InternedString, P<Expr>)>,
+    pub clobbers: HirVec<InternedString>,
     pub volatile: bool,
     pub alignstack: bool,
     pub dialect: AsmDialect,
@@ -1008,7 +1025,7 @@ pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
 /// Represents the header (not the body) of a function declaration
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct FnDecl {
-    pub inputs: Vec<Arg>,
+    pub inputs: HirVec<Arg>,
     pub output: FunctionRetTy,
     pub variadic: bool,
 }
@@ -1099,24 +1116,24 @@ pub struct Mod {
     /// For `mod foo;`, the inner span ranges from the first token
     /// to the last token in the external file.
     pub inner: Span,
-    pub item_ids: Vec<ItemId>,
+    pub item_ids: HirVec<ItemId>,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct ForeignMod {
     pub abi: Abi,
-    pub items: Vec<ForeignItem>,
+    pub items: HirVec<ForeignItem>,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct EnumDef {
-    pub variants: Vec<Variant>,
+    pub variants: HirVec<Variant>,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct Variant_ {
     pub name: Name,
-    pub attrs: Vec<Attribute>,
+    pub attrs: HirVec<Attribute>,
     pub data: VariantData,
     /// Explicit discriminant, eg `Foo = 1`
     pub disr_expr: Option<P<Expr>>,
@@ -1177,7 +1194,7 @@ pub enum ViewPath_ {
     ViewPathGlob(Path),
 
     /// `foo::bar::{a,b,c}`
-    ViewPathList(Path, Vec<PathListItem>),
+    ViewPathList(Path, HirVec<PathListItem>),
 }
 
 /// TraitRef's appear in impls.
@@ -1195,7 +1212,7 @@ pub struct TraitRef {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct PolyTraitRef {
     /// The `'a` in `<'a> Foo<&'a T>`
-    pub bound_lifetimes: Vec<LifetimeDef>,
+    pub bound_lifetimes: HirVec<LifetimeDef>,
 
     /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
     pub trait_ref: TraitRef,
@@ -1223,7 +1240,7 @@ pub struct StructField_ {
     pub kind: StructFieldKind,
     pub id: NodeId,
     pub ty: P<Ty>,
-    pub attrs: Vec<Attribute>,
+    pub attrs: HirVec<Attribute>,
 }
 
 impl StructField_ {
@@ -1272,8 +1289,8 @@ pub fn visibility(&self) -> Visibility {
 /// Id of the whole struct lives in `Item`.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum VariantData {
-    Struct(Vec<StructField>, NodeId),
-    Tuple(Vec<StructField>, NodeId),
+    Struct(HirVec<StructField>, NodeId),
+    Tuple(HirVec<StructField>, NodeId),
     Unit(NodeId),
 }
 
@@ -1328,7 +1345,7 @@ pub struct ItemId {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct Item {
     pub name: Name,
-    pub attrs: Vec<Attribute>,
+    pub attrs: HirVec<Attribute>,
     pub id: NodeId,
     pub node: Item_,
     pub vis: Visibility,
@@ -1361,7 +1378,7 @@ pub enum Item_ {
     /// A struct definition, e.g. `struct Foo<A> {x: A}`
     ItemStruct(VariantData, Generics),
     /// Represents a Trait Declaration
-    ItemTrait(Unsafety, Generics, TyParamBounds, Vec<TraitItem>),
+    ItemTrait(Unsafety, Generics, TyParamBounds, HirVec<TraitItem>),
 
     // Default trait implementations
     ///
@@ -1373,7 +1390,7 @@ pub enum Item_ {
              Generics,
              Option<TraitRef>, // (optional) trait this impl implements
              P<Ty>, // self
-             Vec<ImplItem>),
+             HirVec<ImplItem>),
 }
 
 impl Item_ {
@@ -1399,7 +1416,7 @@ pub fn descriptive_variant(&self) -> &str {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct ForeignItem {
     pub name: Name,
-    pub attrs: Vec<Attribute>,
+    pub attrs: HirVec<Attribute>,
     pub node: ForeignItem_,
     pub id: NodeId,
     pub span: Span,
index 3bfa645afc7d92f9b3f85434484edda66dddcf06..60080854a6f1724441b3ce75f405220aa71b5268 100644 (file)
@@ -47,6 +47,7 @@
 
 extern crate serialize as rustc_serialize; // used by deriving
 
+#[macro_use]
 pub mod hir;
 pub mod lowering;
 pub mod fold;
index c0b10fb89124a9ba07a173a3ff8c80548f3afb8e..db30ee9a5d2d351b7c61816edcd3fb45ac9a62e5 100644 (file)
@@ -70,7 +70,6 @@
 use syntax::ext::mtwt;
 use syntax::ptr::P;
 use syntax::codemap::{respan, Spanned, Span};
-use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token;
 use syntax::std_inject;
 use syntax::visit::{self, Visitor};
@@ -148,6 +147,10 @@ pub fn lower_ident(_lctx: &LoweringContext, ident: Ident) -> hir::Ident {
     }
 }
 
+pub fn lower_attrs(_lctx: &LoweringContext, attrs: &Vec<Attribute>) -> hir::HirVec<Attribute> {
+    attrs.clone().into()
+}
+
 pub fn lower_view_path(lctx: &LoweringContext, view_path: &ViewPath) -> P<hir::ViewPath> {
     P(Spanned {
         node: match view_path.node {
@@ -187,7 +190,7 @@ pub fn lower_view_path(lctx: &LoweringContext, view_path: &ViewPath) -> P<hir::V
 
 pub fn lower_arm(lctx: &LoweringContext, arm: &Arm) -> hir::Arm {
     hir::Arm {
-        attrs: arm.attrs.clone(),
+        attrs: lower_attrs(lctx, &arm.attrs),
         pats: arm.pats.iter().map(|x| lower_pat(lctx, x)).collect(),
         guard: arm.guard.as_ref().map(|ref x| lower_expr(lctx, x)),
         body: lower_expr(lctx, &arm.body),
@@ -276,7 +279,7 @@ pub fn lower_variant(lctx: &LoweringContext, v: &Variant) -> hir::Variant {
     Spanned {
         node: hir::Variant_ {
             name: v.node.name.name,
-            attrs: v.node.attrs.clone(),
+            attrs: lower_attrs(lctx, &v.node.attrs),
             data: lower_variant_data(lctx, &v.node.data),
             disr_expr: v.node.disr_expr.as_ref().map(|e| lower_expr(lctx, e)),
         },
@@ -430,8 +433,8 @@ pub fn lower_ty_param(lctx: &LoweringContext, tp: &TyParam) -> hir::TyParam {
 }
 
 pub fn lower_ty_params(lctx: &LoweringContext,
-                       tps: &OwnedSlice<TyParam>)
-                       -> OwnedSlice<hir::TyParam> {
+                       tps: &P<[TyParam]>)
+                       -> P<[hir::TyParam]> {
     tps.iter().map(|tp| lower_ty_param(lctx, tp)).collect()
 }
 
@@ -450,13 +453,13 @@ pub fn lower_lifetime_def(lctx: &LoweringContext, l: &LifetimeDef) -> hir::Lifet
     }
 }
 
-pub fn lower_lifetimes(lctx: &LoweringContext, lts: &Vec<Lifetime>) -> Vec<hir::Lifetime> {
+pub fn lower_lifetimes(lctx: &LoweringContext, lts: &Vec<Lifetime>) -> hir::HirVec<hir::Lifetime> {
     lts.iter().map(|l| lower_lifetime(lctx, l)).collect()
 }
 
 pub fn lower_lifetime_defs(lctx: &LoweringContext,
                            lts: &Vec<LifetimeDef>)
-                           -> Vec<hir::LifetimeDef> {
+                           -> hir::HirVec<hir::LifetimeDef> {
     lts.iter().map(|l| lower_lifetime_def(lctx, l)).collect()
 }
 
@@ -561,7 +564,7 @@ pub fn lower_struct_field(lctx: &LoweringContext, f: &StructField) -> hir::Struc
             id: f.node.id,
             kind: lower_struct_field_kind(lctx, &f.node.kind),
             ty: lower_ty(lctx, &f.node.ty),
-            attrs: f.node.attrs.clone(),
+            attrs: lower_attrs(lctx, &f.node.attrs),
         },
         span: f.span,
     }
@@ -583,8 +586,8 @@ pub fn lower_mt(lctx: &LoweringContext, mt: &MutTy) -> hir::MutTy {
 }
 
 pub fn lower_opt_bounds(lctx: &LoweringContext,
-                        b: &Option<OwnedSlice<TyParamBound>>)
-                        -> Option<OwnedSlice<hir::TyParamBound>> {
+                        b: &Option<TyParamBounds>)
+                        -> Option<hir::TyParamBounds> {
     b.as_ref().map(|ref bounds| lower_bounds(lctx, bounds))
 }
 
@@ -674,7 +677,7 @@ pub fn lower_trait_item(lctx: &LoweringContext, i: &TraitItem) -> hir::TraitItem
     hir::TraitItem {
         id: i.id,
         name: i.ident.name,
-        attrs: i.attrs.clone(),
+        attrs: lower_attrs(lctx, &i.attrs),
         node: match i.node {
             ConstTraitItem(ref ty, ref default) => {
                 hir::ConstTraitItem(lower_ty(lctx, ty),
@@ -697,7 +700,7 @@ pub fn lower_impl_item(lctx: &LoweringContext, i: &ImplItem) -> hir::ImplItem {
     hir::ImplItem {
         id: i.id,
         name: i.ident.name,
-        attrs: i.attrs.clone(),
+        attrs: lower_attrs(lctx, &i.attrs),
         vis: lower_visibility(lctx, i.vis),
         node: match i.node {
             ImplItemKind::Const(ref ty, ref expr) => {
@@ -741,25 +744,25 @@ pub fn lower_crate(lctx: &LoweringContext, c: &Crate) -> hir::Crate {
 
     hir::Crate {
         module: lower_mod(lctx, &c.module),
-        attrs: c.attrs.clone(),
-        config: c.config.clone(),
+        attrs: lower_attrs(lctx, &c.attrs),
+        config: c.config.clone().into(),
         span: c.span,
         exported_macros: c.exported_macros.iter().map(|m| lower_macro_def(lctx, m)).collect(),
         items: items,
     }
 }
 
-pub fn lower_macro_def(_lctx: &LoweringContext, m: &MacroDef) -> hir::MacroDef {
+pub fn lower_macro_def(lctx: &LoweringContext, m: &MacroDef) -> hir::MacroDef {
     hir::MacroDef {
         name: m.ident.name,
-        attrs: m.attrs.clone(),
+        attrs: lower_attrs(lctx, &m.attrs),
         id: m.id,
         span: m.span,
         imported_from: m.imported_from.map(|x| x.name),
         export: m.export,
         use_locally: m.use_locally,
         allow_internal_unstable: m.allow_internal_unstable,
-        body: m.body.clone(),
+        body: m.body.clone().into(),
     }
 }
 
@@ -773,7 +776,7 @@ pub fn lower_item(lctx: &LoweringContext, i: &Item) -> hir::Item {
     hir::Item {
         id: i.id,
         name: i.ident.name,
-        attrs: i.attrs.clone(),
+        attrs: lower_attrs(lctx, &i.attrs),
         node: node,
         vis: lower_visibility(lctx, i.vis),
         span: i.span,
@@ -784,7 +787,7 @@ pub fn lower_foreign_item(lctx: &LoweringContext, i: &ForeignItem) -> hir::Forei
     hir::ForeignItem {
         id: i.id,
         name: i.ident.name,
-        attrs: i.attrs.clone(),
+        attrs: lower_attrs(lctx, &i.attrs),
         node: match i.node {
             ForeignItemFn(ref fdec, ref generics) => {
                 hir::ForeignItemFn(lower_fn_decl(lctx, fdec), lower_generics(lctx, generics))
@@ -1021,7 +1024,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                     // let placer = <placer_expr> ;
                     let s1 = {
                         let placer_expr = signal_block_expr(lctx,
-                                                            vec![],
+                                                            hir_vec![],
                                                             placer_expr,
                                                             e.span,
                                                             hir::PopUnstableBlock,
@@ -1032,14 +1035,14 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                     // let mut place = Placer::make_place(placer);
                     let s2 = {
                         let placer = expr_ident(lctx, e.span, placer_ident, None);
-                        let call = make_call(lctx, &make_place, vec![placer]);
+                        let call = make_call(lctx, &make_place, hir_vec![placer]);
                         mk_stmt_let_mut(lctx, place_ident, call)
                     };
 
                     // let p_ptr = Place::pointer(&mut place);
                     let s3 = {
                         let agent = expr_ident(lctx, e.span, place_ident, None);
-                        let args = vec![expr_mut_addr_of(lctx, e.span, agent, None)];
+                        let args = hir_vec![expr_mut_addr_of(lctx, e.span, agent, None)];
                         let call = make_call(lctx, &place_pointer, args);
                         mk_stmt_let(lctx, p_ptr_ident, call)
                     };
@@ -1047,13 +1050,13 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                     // pop_unsafe!(EXPR));
                     let pop_unsafe_expr = {
                         let value_expr = signal_block_expr(lctx,
-                                                           vec![],
+                                                           hir_vec![],
                                                            value_expr,
                                                            e.span,
                                                            hir::PopUnstableBlock,
                                                            None);
                         signal_block_expr(lctx,
-                                          vec![],
+                                          hir_vec![],
                                           value_expr,
                                           e.span,
                                           hir::PopUnsafeBlock(hir::CompilerGenerated), None)
@@ -1067,21 +1070,21 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                         let ptr = expr_ident(lctx, e.span, p_ptr_ident, None);
                         let call_move_val_init =
                             hir::StmtSemi(
-                                make_call(lctx, &move_val_init, vec![ptr, pop_unsafe_expr]),
+                                make_call(lctx, &move_val_init, hir_vec![ptr, pop_unsafe_expr]),
                                 lctx.next_id());
                         let call_move_val_init = respan(e.span, call_move_val_init);
 
                         let place = expr_ident(lctx, e.span, place_ident, None);
-                        let call = make_call(lctx, &inplace_finalize, vec![place]);
+                        let call = make_call(lctx, &inplace_finalize, hir_vec![place]);
                         signal_block_expr(lctx,
-                                          vec![call_move_val_init],
+                                          hir_vec![call_move_val_init],
                                           call,
                                           e.span,
                                           hir::PushUnsafeBlock(hir::CompilerGenerated), None)
                     };
 
                     signal_block_expr(lctx,
-                                      vec![s1, s2, s3],
+                                      hir_vec![s1, s2, s3],
                                       expr,
                                       e.span,
                                       hir::PushUnstableBlock,
@@ -1142,7 +1145,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                                 let els = lower_expr(lctx, els);
                                 let id = lctx.next_id();
                                 let blk = P(hir::Block {
-                                    stmts: vec![],
+                                    stmts: hir_vec![],
                                     expr: Some(els),
                                     id: id,
                                     rules: hir::DefaultBlock,
@@ -1239,7 +1242,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                                 .collect(),
                 asm: asm.clone(),
                 asm_str_style: asm_str_style,
-                clobbers: clobbers.clone(),
+                clobbers: clobbers.clone().into(),
                 volatile: volatile,
                 alignstack: alignstack,
                 dialect: dialect,
@@ -1276,7 +1279,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                     let pat_arm = {
                         let body = lower_block(lctx, body);
                         let body_expr = expr_block(lctx, body, None);
-                        arm(vec![lower_pat(lctx, pat)], body_expr)
+                        arm(hir_vec![lower_pat(lctx, pat)], body_expr)
                     };
 
                     // `[_ if <else_opt_if_cond> => <else_opt_if_body>,]`
@@ -1291,8 +1294,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                                         hir::ExprIf(cond, then, else_opt) => {
                                             let pat_under = pat_wild(lctx, e.span);
                                             arms.push(hir::Arm {
-                                                attrs: vec![],
-                                                pats: vec![pat_under],
+                                                attrs: hir_vec![],
+                                                pats: hir_vec![pat_under],
                                                 guard: Some(cond),
                                                 body: expr_block(lctx, then, None),
                                             });
@@ -1326,8 +1329,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                         let pat_under = pat_wild(lctx, e.span);
                         let else_expr =
                             else_opt.unwrap_or_else(
-                                || expr_tuple(lctx, e.span, vec![], None));
-                        arm(vec![pat_under], else_expr)
+                                || expr_tuple(lctx, e.span, hir_vec![], None));
+                        arm(hir_vec![pat_under], else_expr)
                     };
 
                     let mut arms = Vec::with_capacity(else_if_arms.len() + 2);
@@ -1340,7 +1343,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                     expr(lctx,
                          e.span,
                          hir::ExprMatch(sub_expr,
-                                        arms,
+                                        arms.into(),
                                         hir::MatchSource::IfLetDesugar {
                                             contains_else_clause: contains_else_clause,
                                         }),
@@ -1365,18 +1368,18 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                     let pat_arm = {
                         let body = lower_block(lctx, body);
                         let body_expr = expr_block(lctx, body, None);
-                        arm(vec![lower_pat(lctx, pat)], body_expr)
+                        arm(hir_vec![lower_pat(lctx, pat)], body_expr)
                     };
 
                     // `_ => break`
                     let break_arm = {
                         let pat_under = pat_wild(lctx, e.span);
                         let break_expr = expr_break(lctx, e.span, None);
-                        arm(vec![pat_under], break_expr)
+                        arm(hir_vec![pat_under], break_expr)
                     };
 
                     // `match <sub_expr> { ... }`
-                    let arms = vec![pat_arm, break_arm];
+                    let arms = hir_vec![pat_arm, break_arm];
                     let sub_expr = lower_expr(lctx, sub_expr);
                     let match_expr = expr(lctx,
                                           e.span,
@@ -1432,14 +1435,14 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                         let pat = lower_pat(lctx, pat);
                         let some_pat = pat_some(lctx, e.span, pat);
 
-                        arm(vec![some_pat], body_expr)
+                        arm(hir_vec![some_pat], body_expr)
                     };
 
                     // `::std::option::Option::None => break`
                     let break_arm = {
                         let break_expr = expr_break(lctx, e.span, None);
 
-                        arm(vec![pat_none(lctx, e.span)], break_expr)
+                        arm(hir_vec![pat_none(lctx, e.span)], break_expr)
                     };
 
                     // `match ::std::iter::Iterator::next(&mut iter) { ... }`
@@ -1455,9 +1458,9 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                         let next_expr = expr_call(lctx,
                                                   e.span,
                                                   next_path,
-                                                  vec![ref_mut_iter],
+                                                  hir_vec![ref_mut_iter],
                                                   None);
-                        let arms = vec![pat_arm, break_arm];
+                        let arms = hir_vec![pat_arm, break_arm];
 
                         expr(lctx,
                              e.span,
@@ -1477,7 +1480,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                                                               e.span,
                                                               iter,
                                                               hir::BindByValue(hir::MutMutable));
-                        arm(vec![iter_pat], loop_expr)
+                        arm(hir_vec![iter_pat], loop_expr)
                     };
 
                     // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
@@ -1489,13 +1492,13 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                         };
 
                         let into_iter = expr_path(lctx, into_iter_path, None);
-                        expr_call(lctx, e.span, into_iter, vec![head], None)
+                        expr_call(lctx, e.span, into_iter, hir_vec![head], None)
                     };
 
                     let match_expr = expr_match(lctx,
                                                 e.span,
                                                 into_iter_expr,
-                                                vec![iter_arm],
+                                                hir_vec![iter_arm],
                                                 hir::MatchSource::ForLoopDesugar,
                                                 None);
 
@@ -1503,7 +1506,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                     let result_ident = lctx.str_to_ident("result");
                     let let_stmt = stmt_let(lctx, e.span, false, result_ident, match_expr, None);
                     let result = expr_ident(lctx, e.span, result_ident, None);
-                    let block = block_all(lctx, e.span, vec![let_stmt], Some(result));
+                    let block = block_all(lctx, e.span, hir_vec![let_stmt], Some(result));
                     // add the attributes to the outer returned expr node
                     expr_block(lctx, block, e.attrs.clone())
                 });
@@ -1602,9 +1605,9 @@ pub fn lower_trait_bound_modifier(_lctx: &LoweringContext,
 
 // Helper methods for building HIR.
 
-fn arm(pats: Vec<P<hir::Pat>>, expr: P<hir::Expr>) -> hir::Arm {
+fn arm(pats: hir::HirVec<P<hir::Pat>>, expr: P<hir::Expr>) -> hir::Arm {
     hir::Arm {
-        attrs: vec![],
+        attrs: hir_vec![],
         pats: pats,
         guard: None,
         body: expr,
@@ -1619,7 +1622,7 @@ fn expr_break(lctx: &LoweringContext, span: Span,
 fn expr_call(lctx: &LoweringContext,
              span: Span,
              e: P<hir::Expr>,
-             args: Vec<P<hir::Expr>>,
+             args: hir::HirVec<P<hir::Expr>>,
              attrs: ThinAttributes)
              -> P<hir::Expr> {
     expr(lctx, span, hir::ExprCall(e, args), attrs)
@@ -1643,7 +1646,7 @@ fn expr_path(lctx: &LoweringContext, path: hir::Path,
 fn expr_match(lctx: &LoweringContext,
               span: Span,
               arg: P<hir::Expr>,
-              arms: Vec<hir::Arm>,
+              arms: hir::HirVec<hir::Arm>,
               source: hir::MatchSource,
               attrs: ThinAttributes)
               -> P<hir::Expr> {
@@ -1655,7 +1658,7 @@ fn expr_block(lctx: &LoweringContext, b: P<hir::Block>,
     expr(lctx, b.span, hir::ExprBlock(b), attrs)
 }
 
-fn expr_tuple(lctx: &LoweringContext, sp: Span, exprs: Vec<P<hir::Expr>>,
+fn expr_tuple(lctx: &LoweringContext, sp: Span, exprs: hir::HirVec<P<hir::Expr>>,
               attrs: ThinAttributes) -> P<hir::Expr> {
     expr(lctx, sp, hir::ExprTup(exprs), attrs)
 }
@@ -1695,12 +1698,12 @@ fn stmt_let(lctx: &LoweringContext,
 }
 
 fn block_expr(lctx: &LoweringContext, expr: P<hir::Expr>) -> P<hir::Block> {
-    block_all(lctx, expr.span, Vec::new(), Some(expr))
+    block_all(lctx, expr.span, hir::HirVec::new(), Some(expr))
 }
 
 fn block_all(lctx: &LoweringContext,
              span: Span,
-             stmts: Vec<hir::Stmt>,
+             stmts: hir::HirVec<hir::Stmt>,
              expr: Option<P<hir::Expr>>)
              -> P<hir::Block> {
     P(hir::Block {
@@ -1715,19 +1718,19 @@ fn block_all(lctx: &LoweringContext,
 fn pat_some(lctx: &LoweringContext, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
     let some = std_path(lctx, &["option", "Option", "Some"]);
     let path = path_global(span, some);
-    pat_enum(lctx, span, path, vec![pat])
+    pat_enum(lctx, span, path, hir_vec![pat])
 }
 
 fn pat_none(lctx: &LoweringContext, span: Span) -> P<hir::Pat> {
     let none = std_path(lctx, &["option", "Option", "None"]);
     let path = path_global(span, none);
-    pat_enum(lctx, span, path, vec![])
+    pat_enum(lctx, span, path, hir_vec![])
 }
 
 fn pat_enum(lctx: &LoweringContext,
             span: Span,
             path: hir::Path,
-            subpats: Vec<P<hir::Pat>>)
+            subpats: hir::HirVec<P<hir::Pat>>)
             -> P<hir::Pat> {
     let pt = hir::PatEnum(path, Some(subpats));
     pat(lctx, span, pt)
@@ -1768,17 +1771,17 @@ fn path_ident(span: Span, id: hir::Ident) -> hir::Path {
 }
 
 fn path(span: Span, strs: Vec<hir::Ident>) -> hir::Path {
-    path_all(span, false, strs, Vec::new(), Vec::new(), Vec::new())
+    path_all(span, false, strs, hir::HirVec::new(), Vec::new(), Vec::new())
 }
 
 fn path_global(span: Span, strs: Vec<hir::Ident>) -> hir::Path {
-    path_all(span, true, strs, Vec::new(), Vec::new(), Vec::new())
+    path_all(span, true, strs, hir::HirVec::new(), Vec::new(), Vec::new())
 }
 
 fn path_all(sp: Span,
             global: bool,
             mut idents: Vec<hir::Ident>,
-            lifetimes: Vec<hir::Lifetime>,
+            lifetimes: hir::HirVec<hir::Lifetime>,
             types: Vec<P<hir::Ty>>,
             bindings: Vec<hir::TypeBinding>)
             -> hir::Path {
@@ -1795,14 +1798,14 @@ fn path_all(sp: Span,
         identifier: last_identifier,
         parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData {
             lifetimes: lifetimes,
-            types: OwnedSlice::from_vec(types),
-            bindings: OwnedSlice::from_vec(bindings),
+            types: P::from_vec(types),
+            bindings: P::from_vec(bindings),
         }),
     });
     hir::Path {
         span: sp,
         global: global,
-        segments: segments,
+        segments: segments.into(),
     }
 }
 
@@ -1823,7 +1826,7 @@ fn core_path(lctx: &LoweringContext, span: Span, components: &[&str]) -> hir::Pa
 }
 
 fn signal_block_expr(lctx: &LoweringContext,
-                     stmts: Vec<hir::Stmt>,
+                     stmts: hir::HirVec<hir::Stmt>,
                      expr: P<hir::Expr>,
                      span: Span,
                      rule: hir::BlockCheckMode,
index 81076b6e4027698e033c80549efdfae96217ca6f..9ac0e65cba33b051e841e38f4648dc6c02b2e247 100644 (file)
@@ -12,9 +12,8 @@
 
 use syntax::abi;
 use syntax::ast;
-use syntax::owned_slice::OwnedSlice;
 use syntax::codemap::{self, CodeMap, BytePos, Spanned};
-use syntax::diagnostic;
+use syntax::errors;
 use syntax::parse::token::{self, BinOpToken};
 use syntax::parse::lexer::comments;
 use syntax::parse;
@@ -121,7 +120,7 @@ pub fn rust_printer_annotated<'a>(writer: Box<Write + 'a>,
 /// it can scan the input text for comments and literals to
 /// copy forward.
 pub fn print_crate<'a>(cm: &'a CodeMap,
-                       span_diagnostic: &diagnostic::SpanHandler,
+                       span_diagnostic: &errors::Handler,
                        krate: &hir::Crate,
                        filename: String,
                        input: &mut Read,
@@ -142,7 +141,7 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
 
 impl<'a> State<'a> {
     pub fn new_from_input(cm: &'a CodeMap,
-                          span_diagnostic: &diagnostic::SpanHandler,
+                          span_diagnostic: &errors::Handler,
                           filename: String,
                           input: &mut Read,
                           out: Box<Write + 'a>,
@@ -519,10 +518,10 @@ pub fn print_type(&mut self, ty: &hir::Ty) -> io::Result<()> {
             hir::TyBareFn(ref f) => {
                 let generics = hir::Generics {
                     lifetimes: f.lifetimes.clone(),
-                    ty_params: OwnedSlice::empty(),
+                    ty_params: P::empty(),
                     where_clause: hir::WhereClause {
                         id: ast::DUMMY_NODE_ID,
-                        predicates: Vec::new(),
+                        predicates: hir::HirVec::new(),
                     },
                 };
                 try!(self.print_ty_fn(f.abi, f.unsafety, &*f.decl, None, &generics, None));
@@ -2257,11 +2256,11 @@ pub fn print_ty_fn(&mut self,
             try!(self.print_generics(generics));
         }
         let generics = hir::Generics {
-            lifetimes: Vec::new(),
-            ty_params: OwnedSlice::empty(),
+            lifetimes: hir::HirVec::new(),
+            ty_params: P::empty(),
             where_clause: hir::WhereClause {
                 id: ast::DUMMY_NODE_ID,
-                predicates: Vec::new(),
+                predicates: hir::HirVec::new(),
             },
         };
         try!(self.print_fn(decl,
index 4dc08f7a0485acdc5c7dbe3fc0d3167efcdf36bd..298904d1e0d7abdcf82df68c090b3a5cceca64eb 100644 (file)
@@ -15,7 +15,6 @@
 use syntax::ast::{Name, NodeId, DUMMY_NODE_ID};
 use syntax::codemap::Span;
 use syntax::ptr::P;
-use syntax::owned_slice::OwnedSlice;
 
 pub fn walk_pat<F>(pat: &Pat, mut it: F) -> bool
     where F: FnMut(&Pat) -> bool
@@ -335,11 +334,11 @@ pub fn is_path(e: P<Expr>) -> bool {
 
 pub fn empty_generics() -> Generics {
     Generics {
-        lifetimes: Vec::new(),
-        ty_params: OwnedSlice::empty(),
+        lifetimes: HirVec::new(),
+        ty_params: P::empty(),
         where_clause: WhereClause {
             id: DUMMY_NODE_ID,
-            predicates: Vec::new(),
+            predicates: HirVec::new(),
         },
     }
 }
@@ -350,13 +349,13 @@ pub fn ident_to_path(s: Span, ident: Ident) -> Path {
     hir::Path {
         span: s,
         global: false,
-        segments: vec!(hir::PathSegment {
+        segments: hir_vec![hir::PathSegment {
             identifier: ident,
             parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData {
-                lifetimes: Vec::new(),
-                types: OwnedSlice::empty(),
-                bindings: OwnedSlice::empty(),
+                lifetimes: HirVec::new(),
+                types: P::empty(),
+                bindings: P::empty(),
             }),
-        }),
+        }],
     }
 }
index 0f05db86742eb4e3c7f9be0b1a5b5cc35ff87c4e..8dcaa4b5064c18095c2ceeb61c48edb37f11b0c3 100644 (file)
@@ -616,6 +616,7 @@ pub fn LLVMModuleCreateWithNameInContext(ModuleID: *const c_char,
                                              C: ContextRef)
                                              -> ModuleRef;
     pub fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef;
+    pub fn LLVMCloneModule(M: ModuleRef) -> ModuleRef;
     pub fn LLVMDisposeModule(M: ModuleRef);
 
     /// Data layout. See Module::getDataLayout.
index 888776eaa56105647b4846ec518241f41cf9f875..cd70172e8fa2112500da97662a9d337d2cd87451 100644 (file)
@@ -44,7 +44,7 @@
 use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID, CrateNum};
 use syntax::attr;
 use syntax::attr::AttrMetaMethods;
-use syntax::diagnostic::SpanHandler;
+use syntax::errors::Handler;
 use syntax::parse::token::special_idents;
 use syntax;
 use rbml::writer::Encoder;
@@ -57,7 +57,7 @@
     Box<FnMut(&EncodeContext, &mut Encoder, InlinedItemRef) + 'a>;
 
 pub struct EncodeParams<'a, 'tcx: 'a> {
-    pub diag: &'a SpanHandler,
+    pub diag: &'a Handler,
     pub tcx: &'a ty::ctxt<'tcx>,
     pub reexports: &'a def::ExportMap,
     pub item_symbols: &'a RefCell<NodeMap<String>>,
@@ -69,7 +69,7 @@ pub struct EncodeParams<'a, 'tcx: 'a> {
 }
 
 pub struct EncodeContext<'a, 'tcx: 'a> {
-    pub diag: &'a SpanHandler,
+    pub diag: &'a Handler,
     pub tcx: &'a ty::ctxt<'tcx>,
     pub reexports: &'a def::ExportMap,
     pub item_symbols: &'a RefCell<NodeMap<String>>,
@@ -275,8 +275,7 @@ fn encode_symbol(ecx: &EncodeContext,
             rbml_w.wr_tagged_str(tag_items_data_item_symbol, x);
         }
         None => {
-            ecx.diag.handler().bug(
-                &format!("encode_symbol: id not found {}", id));
+            ecx.diag.bug(&format!("encode_symbol: id not found {}", id));
         }
     }
 }
index bd9f9c36f631b8ec4aaf467c414377f76b298144..81788e08c7ef2085135b3c90c59f2207cc8ff5d5 100644 (file)
 use rustc_llvm::{False, ObjectFile, mk_section_iter};
 use rustc_llvm::archive_ro::ArchiveRO;
 use syntax::codemap::Span;
-use syntax::diagnostic::SpanHandler;
+use syntax::errors::Handler;
 use rustc_back::target::Target;
 
 use std::cmp;
@@ -697,8 +697,8 @@ fn find_commandline_library(&mut self, locs: &[String]) -> Option<Library> {
     }
 }
 
-pub fn note_crate_name(diag: &SpanHandler, name: &str) {
-    diag.handler().note(&format!("crate name: {}", name));
+pub fn note_crate_name(diag: &Handler, name: &str) {
+    diag.note(&format!("crate name: {}", name));
 }
 
 impl ArchiveMetadata {
index c1910e3f249db3a74d5674d14257bb3aedf19da3..0119f1d5cc109bc0343148da32c62f4036b464a5 100644 (file)
 
 use syntax::abi::Abi;
 use syntax::ast;
-use syntax::diagnostic::SpanHandler;
+use syntax::errors::Handler;
 
 use rbml::writer::{self, Encoder};
 
 macro_rules! mywrite { ($w:expr, $($arg:tt)*) => ({ write!($w.writer, $($arg)*); }) }
 
 pub struct ctxt<'a, 'tcx: 'a> {
-    pub diag: &'a SpanHandler,
+    pub diag: &'a Handler,
     // Def -> str Callback:
     pub ds: fn(DefId) -> String,
     // The type context.
@@ -136,7 +136,7 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
             enc_bare_fn_ty(w, cx, f);
         }
         ty::TyInfer(_) => {
-            cx.diag.handler().bug("cannot encode inference variable types");
+            cx.diag.bug("cannot encode inference variable types");
         }
         ty::TyParam(ParamTy {space, idx, name}) => {
             mywrite!(w, "p[{}|{}|{}]", idx, space.to_uint(), name)
@@ -279,7 +279,7 @@ pub fn enc_region(w: &mut Encoder, cx: &ctxt, r: ty::Region) {
         }
         ty::ReVar(_) | ty::ReSkolemized(..) => {
             // these should not crop up after typeck
-            cx.diag.handler().bug("cannot encode region variables");
+            cx.diag.bug("cannot encode region variables");
         }
     }
 }
index c32efcd1a7dab03c322bae69896453e42678c86b..8f3a1c17440fc56204f3fec8a20da367f5b4ed0c 100644 (file)
@@ -256,7 +256,7 @@ fn to_pat(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
         }
     }
 
-    fn to_pats(&mut self, pats: &'tcx Vec<P<hir::Pat>>) -> Vec<Pattern<'tcx>> {
+    fn to_pats(&mut self, pats: &'tcx [P<hir::Pat>]) -> Vec<Pattern<'tcx>> {
         pats.iter().map(|p| self.to_pat(p)).collect()
     }
 
@@ -267,9 +267,9 @@ fn to_opt_pat(&mut self, pat: &'tcx Option<P<hir::Pat>>) -> Option<Pattern<'tcx>
     fn slice_or_array_pattern(&mut self,
                               pat: &'tcx hir::Pat,
                               ty: Ty<'tcx>,
-                              prefix: &'tcx Vec<P<hir::Pat>>,
+                              prefix: &'tcx [P<hir::Pat>],
                               slice: &'tcx Option<P<hir::Pat>>,
-                              suffix: &'tcx Vec<P<hir::Pat>>)
+                              suffix: &'tcx [P<hir::Pat>])
                               -> PatternKind<'tcx> {
         match ty.sty {
             ty::TySlice(..) => {
index 00f58c6af91554d8e63e6b1234e40be39413db70..476425a75c22df73bb61953d0bf6cb2a124130bf 100644 (file)
@@ -13,7 +13,7 @@
 use syntax::ast;
 use syntax::attr;
 use syntax::codemap::Span;
-use syntax::diagnostic;
+use syntax::errors;
 use rustc_front::intravisit::Visitor;
 use rustc_front::hir;
 
@@ -33,7 +33,7 @@ fn visit_item(&mut self, item: &hir::Item) {
 }
 
 /// Find the function marked with `#[plugin_registrar]`, if any.
-pub fn find_plugin_registrar(diagnostic: &diagnostic::SpanHandler,
+pub fn find_plugin_registrar(diagnostic: &errors::Handler,
                              krate: &hir::Crate)
                              -> Option<ast::NodeId> {
     let mut finder = RegistrarFinder { registrars: Vec::new() };
@@ -46,11 +46,11 @@ pub fn find_plugin_registrar(diagnostic: &diagnostic::SpanHandler,
             Some(node_id)
         },
         _ => {
-            diagnostic.handler().err("multiple plugin registration functions found");
+            diagnostic.err("multiple plugin registration functions found");
             for &(_, span) in &finder.registrars {
                 diagnostic.span_note(span, "one is here");
             }
-            diagnostic.handler().abort_if_errors();
+            diagnostic.abort_if_errors();
             unreachable!();
         }
     }
index ba6ec895a8e12e356d23f3094ad5e99a9cfb9ddc..8505c3968ee15ea761187821777340880c96416d 100644 (file)
@@ -101,7 +101,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
                 if !llvm::LLVMRustLinkInExternalBitcode(llmod,
                                                         ptr as *const libc::c_char,
                                                         bc_decoded.len() as libc::size_t) {
-                    write::llvm_err(sess.diagnostic().handler(),
+                    write::llvm_err(sess.diagnostic(),
                                     format!("failed to load bc of `{}`",
                                             &name[..]));
                 }
index 4815a399d991384b8743b4ffab87d1dfaaf0d634..67eff1ca19fbc1957764576c1e213aa9245142fa 100644 (file)
@@ -20,8 +20,8 @@
 use util::common::time;
 use util::common::path2cstr;
 use syntax::codemap;
-use syntax::diagnostic;
-use syntax::diagnostic::{Emitter, Handler, Level};
+use syntax::errors::{self, Handler, Level};
+use syntax::errors::emitter::Emitter;
 
 use std::collections::HashMap;
 use std::ffi::{CStr, CString};
@@ -34,7 +34,7 @@
 use std::thread;
 use libc::{self, c_uint, c_int, c_void};
 
-pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! {
+pub fn llvm_err(handler: &errors::Handler, msg: String) -> ! {
     unsafe {
         let cstr = llvm::LLVMRustGetLastError();
         if cstr == ptr::null() {
@@ -49,7 +49,7 @@ pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! {
 }
 
 pub fn write_output_file(
-        handler: &diagnostic::Handler,
+        handler: &errors::Handler,
         target: llvm::TargetMachineRef,
         pm: llvm::PassManagerRef,
         m: ModuleRef,
@@ -109,9 +109,9 @@ fn dump(&mut self, handler: &Handler) {
 }
 
 impl Emitter for SharedEmitter {
-    fn emit(&mut self, cmsp: Option<(&codemap::CodeMap, codemap::Span)>,
+    fn emit(&mut self, sp: Option<codemap::Span>,
             msg: &str, code: Option<&str>, lvl: Level) {
-        assert!(cmsp.is_none(), "SharedEmitter doesn't support spans");
+        assert!(sp.is_none(), "SharedEmitter doesn't support spans");
 
         self.buffer.lock().unwrap().push(Diagnostic {
             msg: msg.to_string(),
@@ -120,8 +120,7 @@ fn emit(&mut self, cmsp: Option<(&codemap::CodeMap, codemap::Span)>,
         });
     }
 
-    fn custom_emit(&mut self, _cm: &codemap::CodeMap,
-                   _sp: diagnostic::RenderSpan, _msg: &str, _lvl: Level) {
+    fn custom_emit(&mut self, _sp: errors::RenderSpan, _msg: &str, _lvl: Level) {
         panic!("SharedEmitter doesn't support custom_emit");
     }
 }
@@ -226,7 +225,7 @@ pub fn create_target_machine(sess: &Session) -> TargetMachineRef {
     };
 
     if tm.is_null() {
-        llvm_err(sess.diagnostic().handler(),
+        llvm_err(sess.diagnostic(),
                  format!("Could not create LLVM TargetMachine for triple: {}",
                          triple).to_string());
     } else {
@@ -333,7 +332,7 @@ impl<'a> CodegenContext<'a> {
     fn new_with_session(sess: &'a Session, reachable: &'a [String]) -> CodegenContext<'a> {
         CodegenContext {
             lto_ctxt: Some((sess, reachable)),
-            handler: sess.diagnostic().handler(),
+            handler: sess.diagnostic(),
             plugin_passes: sess.plugin_llvm_passes.borrow().clone(),
             remark: sess.opts.cg.remark.clone(),
             worker: 0,
@@ -545,10 +544,22 @@ unsafe fn with_codegen<F>(tm: TargetMachineRef,
 
         if config.emit_asm {
             let path = output_names.with_extension(&format!("{}.s", name_extra));
+
+            // We can't use the same module for asm and binary output, because that triggers
+            // various errors like invalid IR or broken binaries, so we might have to clone the
+            // module to produce the asm output
+            let llmod = if config.emit_obj {
+                llvm::LLVMCloneModule(llmod)
+            } else {
+                llmod
+            };
             with_codegen(tm, llmod, config.no_builtins, |cpm| {
                 write_output_file(cgcx.handler, tm, cpm, llmod, &path,
                                   llvm::AssemblyFileType);
             });
+            if config.emit_obj {
+                llvm::LLVMDisposeModule(llmod);
+            }
         }
 
         if config.emit_obj {
@@ -863,7 +874,7 @@ fn run_work_multithreaded(sess: &Session,
         futures.push(rx);
 
         thread::Builder::new().name(format!("codegen-{}", i)).spawn(move || {
-            let diag_handler = Handler::with_emitter(true, box diag_emitter);
+            let diag_handler = Handler::with_emitter(true, false, box diag_emitter);
 
             // Must construct cgcx inside the proc because it has non-Send
             // fields.
@@ -903,7 +914,7 @@ fn run_work_multithreaded(sess: &Session,
             },
         }
         // Display any new diagnostics.
-        diag_emitter.dump(sess.diagnostic().handler());
+        diag_emitter.dump(sess.diagnostic());
     }
     if panicked {
         sess.fatal("aborting due to worker thread panic");
index 747b76ae57f1e8eebb0d54f5029d745d1deb5da5..9c6b54e13796de6b9e2682a0a9c50978b841db8e 100644 (file)
@@ -41,7 +41,6 @@
 use syntax::ast::{self, NodeId};
 use syntax::codemap::*;
 use syntax::parse::token::{self, keywords};
-use syntax::owned_slice::OwnedSlice;
 use syntax::visit::{self, Visitor};
 use syntax::print::pprust::{path_to_string, ty_to_string};
 use syntax::ptr::P;
@@ -572,7 +571,7 @@ fn process_impl(&mut self,
     fn process_trait(&mut self,
                      item: &ast::Item,
                      generics: &ast::Generics,
-                     trait_refs: &OwnedSlice<ast::TyParamBound>,
+                     trait_refs: &ast::TyParamBounds,
                      methods: &[P<ast::TraitItem>]) {
         let qualname = format!("::{}", self.tcx.map.path_to_string(item.id));
         let val = self.span.snippet(item.span);
index f6f1918fd074168ec94ea82befa3bddae3e59b1b..c744ef321278d0b6d6b6eb10ce7308a74b124708 100644 (file)
@@ -1165,7 +1165,7 @@ pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, v
 
     let meta = val.meta;
 
-    // Calculate the unaligned offset of the the unsized field.
+    // Calculate the unaligned offset of the unsized field.
     let mut offset = 0;
     for &ty in &st.fields[0..ix] {
         let llty = type_of::sizing_type_of(ccx, ty);
index 966033e9f2566d47958bf6a7122a1bac77d85234..d33beab9313d0f16e2fa4292d08f7c654b5b6ec2 100644 (file)
@@ -20,7 +20,6 @@
 
 use arena::TypedArena;
 use back::link;
-use session;
 use llvm::{self, ValueRef, get_params};
 use middle::cstore::LOCAL_CRATE;
 use middle::def;
@@ -57,6 +56,7 @@
 
 use syntax::abi as synabi;
 use syntax::ast;
+use syntax::errors;
 use syntax::ptr::P;
 
 #[derive(Copy, Clone)]
@@ -412,8 +412,8 @@ fn is_named_tuple_constructor(tcx: &ty::ctxt, def_id: DefId) -> bool {
             Some(n) => n,
             None => { return false; }
         };
-        let map_node = session::expect(
-            &tcx.sess,
+        let map_node = errors::expect(
+            &tcx.sess.diagnostic(),
             tcx.map.find(node_id),
             || "local item should be in ast map".to_string());
 
index 4b33e50ec52182ee57ec66f4e973c4be25fdd9f3..038e699a043ab4d755c17484959defab7227ed98 100644 (file)
@@ -1037,7 +1037,7 @@ pub fn trans_static(ccx: &CrateContext,
                     m: hir::Mutability,
                     expr: &hir::Expr,
                     id: ast::NodeId,
-                    attrs: &Vec<ast::Attribute>)
+                    attrs: &[ast::Attribute])
                     -> Result<ValueRef, ConstEvalErr> {
     unsafe {
         let _icx = push_ctxt("trans_static");
index 9c1fcaff7c89568d65e18bdef88821c864d290b0..4b6a0d1a5096541cd77ba4349c0db612c417bc91 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use back::link::exported_name;
-use session;
 use llvm::ValueRef;
 use llvm;
 use middle::def_id::DefId;
@@ -32,6 +31,7 @@
 use syntax::abi;
 use syntax::ast;
 use syntax::attr;
+use syntax::errors;
 use std::hash::{Hasher, Hash, SipHasher};
 
 pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
@@ -83,8 +83,8 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
            hash_id);
 
 
-    let map_node = session::expect(
-        ccx.sess(),
+    let map_node = errors::expect(
+        ccx.sess().diagnostic(),
         ccx.tcx().map.find(fn_node_id),
         || {
             format!("while monomorphizing {:?}, couldn't find it in \
index 9f453362d24bdf7091d1125b9b351a72d6b601e6..bddf0e9ffb0cb1d205aa00b2c8aff3f1e88010aa 100644 (file)
 use syntax::attr;
 use syntax::attr::AttrMetaMethods;
 use syntax::codemap::{self, Span, Spanned};
-use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token::{self, InternedString};
 use syntax::ptr::P;
 use syntax::util::lev_distance::lev_distance;
@@ -4907,7 +4906,7 @@ pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &hir::Block) -> bool {
 }
 
 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
-                                       tps: &OwnedSlice<hir::TyParam>,
+                                       tps: &P<[hir::TyParam]>,
                                        ty: Ty<'tcx>) {
     debug!("check_bounds_are_used(n_tps={}, ty={:?})",
            tps.len(),  ty);
index 52eeb781b31cccc7cfa22c13717444e5be31cb8f..675eef637b10b7626a83b476ae79a084b7df973b 100644 (file)
@@ -112,7 +112,7 @@ fn clean(&self, cx: &DocContext) -> U {
     }
 }
 
-impl<T: Clean<U>, U> Clean<Vec<U>> for syntax::owned_slice::OwnedSlice<T> {
+impl<T: Clean<U>, U> Clean<Vec<U>> for P<[T]> {
     fn clean(&self, cx: &DocContext) -> Vec<U> {
         self.iter().map(|x| x.clean(cx)).collect()
     }
@@ -1584,8 +1584,13 @@ fn clean(&self, cx: &DocContext) -> Type {
                 resolve_type(cx, p.clean(cx), self.id)
             }
             TyPath(Some(ref qself), ref p) => {
-                let mut trait_path = p.clone();
-                trait_path.segments.pop();
+                let mut segments: Vec<_> = p.segments.clone().into();
+                segments.pop();
+                let trait_path = hir::Path {
+                    span: p.span,
+                    global: p.global,
+                    segments: segments.into(),
+                };
                 Type::QPath {
                     name: p.segments.last().unwrap().identifier.name.clean(cx),
                     self_type: box qself.ty.clean(cx),
index 1ccab1b16ebdb09ee2e91d86ad616b194e31d0f7..c6c98851f7c34af366a5b04575e980f171cf5836 100644 (file)
@@ -22,7 +22,8 @@
 use rustc_front::lowering::{lower_crate, LoweringContext};
 use rustc_metadata::cstore::CStore;
 
-use syntax::{ast, codemap, diagnostic};
+use syntax::{ast, codemap, errors};
+use syntax::errors::emitter::ColorConfig;
 use syntax::feature_gate::UnstableFeatures;
 use syntax::parse::token;
 
@@ -116,15 +117,16 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
         ..config::basic_options().clone()
     };
 
-    let codemap = codemap::CodeMap::new();
-    let diagnostic_handler = diagnostic::Handler::new(diagnostic::Auto, None, true);
-    let span_diagnostic_handler =
-        diagnostic::SpanHandler::new(diagnostic_handler, codemap);
+    let codemap = Rc::new(codemap::CodeMap::new());
+    let diagnostic_handler = errors::Handler::new(ColorConfig::Auto,
+                                                  None,
+                                                  true,
+                                                  false,
+                                                  codemap.clone());
 
     let cstore = Rc::new(CStore::new(token::get_ident_interner()));
     let cstore_ = ::rustc_driver::cstore_to_cratestore(cstore.clone());
-    let sess = session::build_session_(sessopts, cpath,
-                                       span_diagnostic_handler, cstore_);
+    let sess = session::build_session_(sessopts, cpath, diagnostic_handler, codemap, cstore_);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
 
     let mut cfg = config::build_configuration(&sess);
index d1030a6fcb07c56234f99e4dae6298ec072ab0cb..fc0422b3a3f037ad6be59491121c57deb068532f 100644 (file)
@@ -24,7 +24,7 @@
 
 pub struct Module {
     pub name: Option<Name>,
-    pub attrs: Vec<ast::Attribute>,
+    pub attrs: hir::HirVec<ast::Attribute>,
     pub where_outer: Span,
     pub where_inner: Span,
     pub extern_crates: Vec<ExternCrate>,
@@ -58,7 +58,7 @@ pub fn new(name: Option<Name>) -> Module {
             depr: None,
             where_outer: syntax::codemap::DUMMY_SP,
             where_inner: syntax::codemap::DUMMY_SP,
-            attrs      : Vec::new(),
+            attrs      : hir::HirVec::new(),
             extern_crates: Vec::new(),
             imports    : Vec::new(),
             structs    : Vec::new(),
@@ -103,8 +103,8 @@ pub struct Struct {
     pub struct_type: StructType,
     pub name: Name,
     pub generics: hir::Generics,
-    pub attrs: Vec<ast::Attribute>,
-    pub fields: Vec<hir::StructField>,
+    pub attrs: hir::HirVec<ast::Attribute>,
+    pub fields: hir::HirVec<hir::StructField>,
     pub whence: Span,
 }
 
@@ -112,9 +112,9 @@ pub struct Enum {
     pub vis: hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
-    pub variants: Vec<Variant>,
+    pub variants: hir::HirVec<Variant>,
     pub generics: hir::Generics,
-    pub attrs: Vec<ast::Attribute>,
+    pub attrs: hir::HirVec<ast::Attribute>,
     pub id: NodeId,
     pub whence: Span,
     pub name: Name,
@@ -122,7 +122,7 @@ pub struct Enum {
 
 pub struct Variant {
     pub name: Name,
-    pub attrs: Vec<ast::Attribute>,
+    pub attrs: hir::HirVec<ast::Attribute>,
     pub def: hir::VariantData,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
@@ -131,7 +131,7 @@ pub struct Variant {
 
 pub struct Function {
     pub decl: hir::FnDecl,
-    pub attrs: Vec<ast::Attribute>,
+    pub attrs: hir::HirVec<ast::Attribute>,
     pub id: NodeId,
     pub name: Name,
     pub vis: hir::Visibility,
@@ -149,7 +149,7 @@ pub struct Typedef {
     pub gen: hir::Generics,
     pub name: Name,
     pub id: ast::NodeId,
-    pub attrs: Vec<ast::Attribute>,
+    pub attrs: hir::HirVec<ast::Attribute>,
     pub whence: Span,
     pub vis: hir::Visibility,
     pub stab: Option<attr::Stability>,
@@ -162,7 +162,7 @@ pub struct Static {
     pub mutability: hir::Mutability,
     pub expr: P<hir::Expr>,
     pub name: Name,
-    pub attrs: Vec<ast::Attribute>,
+    pub attrs: hir::HirVec<ast::Attribute>,
     pub vis: hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
@@ -174,7 +174,7 @@ pub struct Constant {
     pub type_: P<hir::Ty>,
     pub expr: P<hir::Expr>,
     pub name: Name,
-    pub attrs: Vec<ast::Attribute>,
+    pub attrs: hir::HirVec<ast::Attribute>,
     pub vis: hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
@@ -185,10 +185,10 @@ pub struct Constant {
 pub struct Trait {
     pub unsafety: hir::Unsafety,
     pub name: Name,
-    pub items: Vec<hir::TraitItem>,
+    pub items: hir::HirVec<hir::TraitItem>,
     pub generics: hir::Generics,
-    pub bounds: Vec<hir::TyParamBound>,
-    pub attrs: Vec<ast::Attribute>,
+    pub bounds: hir::HirVec<hir::TyParamBound>,
+    pub attrs: hir::HirVec<ast::Attribute>,
     pub id: ast::NodeId,
     pub whence: Span,
     pub vis: hir::Visibility,
@@ -202,8 +202,8 @@ pub struct Impl {
     pub generics: hir::Generics,
     pub trait_: Option<hir::TraitRef>,
     pub for_: P<hir::Ty>,
-    pub items: Vec<hir::ImplItem>,
-    pub attrs: Vec<ast::Attribute>,
+    pub items: hir::HirVec<hir::ImplItem>,
+    pub attrs: hir::HirVec<ast::Attribute>,
     pub whence: Span,
     pub vis: hir::Visibility,
     pub stab: Option<attr::Stability>,
@@ -215,16 +215,16 @@ pub struct DefaultImpl {
     pub unsafety: hir::Unsafety,
     pub trait_: hir::TraitRef,
     pub id: ast::NodeId,
-    pub attrs: Vec<ast::Attribute>,
+    pub attrs: hir::HirVec<ast::Attribute>,
     pub whence: Span,
 }
 
 pub struct Macro {
     pub name: Name,
     pub id: ast::NodeId,
-    pub attrs: Vec<ast::Attribute>,
+    pub attrs: hir::HirVec<ast::Attribute>,
     pub whence: Span,
-    pub matchers: Vec<Span>,
+    pub matchers: hir::HirVec<Span>,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
     pub imported_from: Option<Name>,
@@ -234,14 +234,14 @@ pub struct ExternCrate {
     pub name: Name,
     pub path: Option<String>,
     pub vis: hir::Visibility,
-    pub attrs: Vec<ast::Attribute>,
+    pub attrs: hir::HirVec<ast::Attribute>,
     pub whence: Span,
 }
 
 pub struct Import {
     pub id: NodeId,
     pub vis: hir::Visibility,
-    pub attrs: Vec<ast::Attribute>,
+    pub attrs: hir::HirVec<ast::Attribute>,
     pub node: hir::ViewPath_,
     pub whence: Span,
 }
index af6510cb3870e1fcf44b9739f30e596c692b68ca..31fdc1170c0261f54dc285cba4ff162f0d27eb58 100644 (file)
@@ -65,7 +65,7 @@
 use serialize::Decodable;
 use serialize::json::{self, Json};
 use rustc::session::search_paths::SearchPaths;
-use syntax::diagnostic;
+use syntax::errors::emitter::ColorConfig;
 
 // reexported from `clean` so it can be easily updated with the mod itself
 pub use clean::SCHEMA_VERSION;
@@ -228,7 +228,7 @@ pub fn main_args(args: &[String]) -> isize {
 
     let mut libs = SearchPaths::new();
     for s in &matches.opt_strs("L") {
-        libs.add_path(s, diagnostic::Auto);
+        libs.add_path(s, ColorConfig::Auto);
     }
     let externs = match parse_externs(&matches) {
         Ok(ex) => ex,
@@ -363,7 +363,7 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
     // First, parse the crate and extract all relevant information.
     let mut paths = SearchPaths::new();
     for s in &matches.opt_strs("L") {
-        paths.add_path(s, diagnostic::Auto);
+        paths.add_path(s, ColorConfig::Auto);
     }
     let cfgs = matches.opt_strs("cfg");
     let triple = matches.opt_str("target");
index 3322794c7781e28827a66df5cb66ebb52a49d445..fde8299d2d2e6f5a37a851df388ab52380e93c12 100644 (file)
@@ -34,7 +34,8 @@
 use rustc_driver::{driver, Compilation};
 use rustc_metadata::cstore::CStore;
 use syntax::codemap::CodeMap;
-use syntax::diagnostic;
+use syntax::errors;
+use syntax::errors::emitter::ColorConfig;
 use syntax::parse::token;
 
 use core;
@@ -71,16 +72,19 @@ pub fn run(input: &str,
         ..config::basic_options().clone()
     };
 
-    let codemap = CodeMap::new();
-    let diagnostic_handler = diagnostic::Handler::new(diagnostic::Auto, None, true);
-    let span_diagnostic_handler =
-    diagnostic::SpanHandler::new(diagnostic_handler, codemap);
+    let codemap = Rc::new(CodeMap::new());
+    let diagnostic_handler = errors::Handler::new(ColorConfig::Auto,
+                                                  None,
+                                                  true,
+                                                  false,
+                                                  codemap.clone());
 
     let cstore = Rc::new(CStore::new(token::get_ident_interner()));
     let cstore_ = ::rustc_driver::cstore_to_cratestore(cstore.clone());
     let sess = session::build_session_(sessopts,
                                        Some(input_path.clone()),
-                                       span_diagnostic_handler,
+                                       diagnostic_handler,
+                                       codemap,
                                        cstore_);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
 
@@ -220,21 +224,22 @@ fn drop(&mut self) {
         }
     }
     let data = Arc::new(Mutex::new(Vec::new()));
-    let emitter = diagnostic::EmitterWriter::new(box Sink(data.clone()), None);
+    let codemap = Rc::new(CodeMap::new());
+    let emitter = errors::emitter::EmitterWriter::new(box Sink(data.clone()),
+                                                      None,
+                                                      codemap.clone());
     let old = io::set_panic(box Sink(data.clone()));
     let _bomb = Bomb(data, old.unwrap_or(box io::stdout()));
 
     // Compile the code
-    let codemap = CodeMap::new();
-    let diagnostic_handler = diagnostic::Handler::with_emitter(true, box emitter);
-    let span_diagnostic_handler =
-        diagnostic::SpanHandler::new(diagnostic_handler, codemap);
+    let diagnostic_handler = errors::Handler::with_emitter(true, false, box emitter);
 
     let cstore = Rc::new(CStore::new(token::get_ident_interner()));
     let cstore_ = ::rustc_driver::cstore_to_cratestore(cstore.clone());
     let sess = session::build_session_(sessopts,
                                        None,
-                                       span_diagnostic_handler,
+                                       diagnostic_handler,
+                                       codemap,
                                        cstore_);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
 
index d95a4553bf1f53b3b33e24a59c26b3c37d46acfe..ba389bc42b78cd30df66543a03e688ef923a9827 100644 (file)
@@ -38,7 +38,7 @@
 
 pub struct RustdocVisitor<'a, 'tcx: 'a> {
     pub module: Module,
-    pub attrs: Vec<ast::Attribute>,
+    pub attrs: hir::HirVec<ast::Attribute>,
     pub cx: &'a core::DocContext<'a, 'tcx>,
     pub analysis: Option<&'a core::CrateAnalysis>,
     view_item_stack: HashSet<ast::NodeId>,
@@ -53,7 +53,7 @@ pub fn new(cx: &'a core::DocContext<'a, 'tcx>,
         stack.insert(ast::CRATE_NODE_ID);
         RustdocVisitor {
             module: Module::new(None),
-            attrs: Vec::new(),
+            attrs: hir::HirVec::new(),
             cx: cx,
             analysis: analysis,
             view_item_stack: stack,
@@ -157,7 +157,7 @@ pub fn visit_fn(&mut self, item: &hir::Item,
         }
     }
 
-    pub fn visit_mod_contents(&mut self, span: Span, attrs: Vec<ast::Attribute> ,
+    pub fn visit_mod_contents(&mut self, span: Span, attrs: hir::HirVec<ast::Attribute>,
                               vis: hir::Visibility, id: ast::NodeId,
                               m: &hir::Mod,
                               name: Option<ast::Name>) -> Module {
@@ -192,7 +192,7 @@ fn visit_view_path(&mut self, path: hir::ViewPath_,
                 let mine = paths.into_iter().filter(|path| {
                     !self.resolve_id(path.node.id(), None, false, om,
                                      please_inline)
-                }).collect::<Vec<hir::PathListItem>>();
+                }).collect::<hir::HirVec<hir::PathListItem>>();
 
                 if mine.is_empty() {
                     None
index d1bd013e67b792a8be8cef92cbe7a46c297cd935..c4f59d51f5dade8aa9c6218b0ecd2ad0e3f08823 100644 (file)
@@ -42,7 +42,7 @@ fn getrandom(buf: &mut [u8]) -> libc::c_long {
         const NR_GETRANDOM: libc::c_long = 355;
         #[cfg(any(target_arch = "arm", target_arch = "powerpc"))]
         const NR_GETRANDOM: libc::c_long = 384;
-        #[cfg(any(target_arch = "aarch64"))]
+        #[cfg(target_arch = "aarch64")]
         const NR_GETRANDOM: libc::c_long = 278;
 
         unsafe {
@@ -60,8 +60,7 @@ fn getrandom(_buf: &mut [u8]) -> libc::c_long { -1 }
 
     fn getrandom_fill_bytes(v: &mut [u8]) {
         let mut read = 0;
-        let len = v.len();
-        while read < len {
+        while read < v.len() {
             let result = getrandom(&mut v[read..]);
             if result == -1 {
                 let err = errno() as libc::c_int;
index de5595eebee71d80e3448eb163683439103a150c..4b0ec8578c12ed5a869d15fb3e8472c10cef5ed0 100644 (file)
@@ -50,7 +50,6 @@
 use abi::Abi;
 use ext::base;
 use ext::tt::macro_parser;
-use owned_slice::OwnedSlice;
 use parse::token::InternedString;
 use parse::token;
 use parse::lexer;
@@ -261,8 +260,8 @@ impl PathParameters {
     pub fn none() -> PathParameters {
         AngleBracketedParameters(AngleBracketedParameterData {
             lifetimes: Vec::new(),
-            types: OwnedSlice::empty(),
-            bindings: OwnedSlice::empty(),
+            types: P::empty(),
+            bindings: P::empty(),
         })
     }
 
@@ -334,10 +333,10 @@ pub struct AngleBracketedParameterData {
     /// The lifetime parameters for this path segment.
     pub lifetimes: Vec<Lifetime>,
     /// The type parameters for this path segment, if present.
-    pub types: OwnedSlice<P<Ty>>,
+    pub types: P<[P<Ty>]>,
     /// Bindings (equality constraints) on associated types, if present.
     /// E.g., `Foo<A=Bar>`.
-    pub bindings: OwnedSlice<P<TypeBinding>>,
+    pub bindings: P<[P<TypeBinding>]>,
 }
 
 impl AngleBracketedParameterData {
@@ -394,7 +393,7 @@ pub enum TraitBoundModifier {
     Maybe,
 }
 
-pub type TyParamBounds = OwnedSlice<TyParamBound>;
+pub type TyParamBounds = P<[TyParamBound]>;
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct TyParam {
@@ -410,7 +409,7 @@ pub struct TyParam {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct Generics {
     pub lifetimes: Vec<LifetimeDef>,
-    pub ty_params: OwnedSlice<TyParam>,
+    pub ty_params: P<[TyParam]>,
     pub where_clause: WhereClause,
 }
 
@@ -430,7 +429,7 @@ impl Default for Generics {
     fn default() ->  Generics {
         Generics {
             lifetimes: Vec::new(),
-            ty_params: OwnedSlice::empty(),
+            ty_params: P::empty(),
             where_clause: WhereClause {
                 id: DUMMY_NODE_ID,
                 predicates: Vec::new(),
@@ -466,7 +465,7 @@ pub struct WhereBoundPredicate {
     /// The type being bounded
     pub bounded_ty: P<Ty>,
     /// Trait and lifetime bounds (`Clone+Send+'static`)
-    pub bounds: OwnedSlice<TyParamBound>,
+    pub bounds: TyParamBounds,
 }
 
 /// A lifetime predicate, e.g. `'a: 'b+'c`
index 3d3d53477494d2baf584568289e8fa751c8510ec..d38b771814c2874ae30e24df88d52523e2ffed68 100644 (file)
@@ -12,7 +12,6 @@
 use ast;
 use codemap;
 use codemap::Span;
-use owned_slice::OwnedSlice;
 use parse::token;
 use print::pprust;
 use ptr::P;
@@ -43,8 +42,8 @@ pub fn ident_to_path(s: Span, identifier: Ident) -> Path {
                 identifier: identifier,
                 parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
                     lifetimes: Vec::new(),
-                    types: OwnedSlice::empty(),
-                    bindings: OwnedSlice::empty(),
+                    types: P::empty(),
+                    bindings: P::empty(),
                 })
             }
         ),
index fcc7351deaaecf517c6dee678fee605cb29ba06f..26662605ba87fb68abab4d729ac722f7d669c3a9 100644 (file)
@@ -21,7 +21,7 @@
 use codemap::{Span, Spanned, spanned, dummy_spanned};
 use codemap::BytePos;
 use config::CfgDiag;
-use diagnostic::SpanHandler;
+use errors::Handler;
 use feature_gate::{GatedCfg, GatedCfgAttr};
 use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
 use parse::token::InternedString;
@@ -299,14 +299,14 @@ pub fn find_crate_name(attrs: &[Attribute]) -> Option<InternedString> {
 }
 
 /// Find the value of #[export_name=*] attribute and check its validity.
-pub fn find_export_name_attr(diag: &SpanHandler, attrs: &[Attribute]) -> Option<InternedString> {
+pub fn find_export_name_attr(diag: &Handler, attrs: &[Attribute]) -> Option<InternedString> {
     attrs.iter().fold(None, |ia,attr| {
         if attr.check_name("export_name") {
             if let s@Some(_) = attr.value_str() {
                 s
             } else {
                 diag.span_err(attr.span, "export_name attribute has invalid format");
-                diag.handler.help("use #[export_name=\"*\"]");
+                diag.help("use #[export_name=\"*\"]");
                 None
             }
         } else {
@@ -324,7 +324,7 @@ pub enum InlineAttr {
 }
 
 /// Determine what `#[inline]` attribute is present in `attrs`, if any.
-pub fn find_inline_attr(diagnostic: Option<&SpanHandler>, attrs: &[Attribute]) -> InlineAttr {
+pub fn find_inline_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> InlineAttr {
     attrs.iter().fold(InlineAttr::None, |ia,attr| {
         match attr.node.value.node {
             MetaWord(ref n) if *n == "inline" => {
@@ -426,7 +426,7 @@ pub fn is_unstable(&self) -> bool { if let Unstable {..} = *self { true } else {
     pub fn is_stable(&self) -> bool { if let Stable {..} = *self { true } else { false }}
 }
 
-fn find_stability_generic<'a, I>(diagnostic: &SpanHandler,
+fn find_stability_generic<'a, I>(diagnostic: &Handler,
                                  attrs_iter: I,
                                  item_sp: Span)
                                  -> Option<Stability>
@@ -612,10 +612,10 @@ fn find_stability_generic<'a, I>(diagnostic: &SpanHandler,
     stab
 }
 
-fn find_deprecation_generic<'a, I>(diagnostic: &SpanHandler,
-                                 attrs_iter: I,
-                                 item_sp: Span)
-                                 -> Option<Deprecation>
+fn find_deprecation_generic<'a, I>(diagnostic: &Handler,
+                                   attrs_iter: I,
+                                   item_sp: Span)
+                                   -> Option<Deprecation>
     where I: Iterator<Item = &'a Attribute>
 {
     let mut depr: Option<Deprecation> = None;
@@ -672,18 +672,18 @@ fn find_deprecation_generic<'a, I>(diagnostic: &SpanHandler,
 }
 
 /// Find the first stability attribute. `None` if none exists.
-pub fn find_stability(diagnostic: &SpanHandler, attrs: &[Attribute],
+pub fn find_stability(diagnostic: &Handler, attrs: &[Attribute],
                       item_sp: Span) -> Option<Stability> {
     find_stability_generic(diagnostic, attrs.iter(), item_sp)
 }
 
 /// Find the deprecation attribute. `None` if none exists.
-pub fn find_deprecation(diagnostic: &SpanHandler, attrs: &[Attribute],
-                      item_sp: Span) -> Option<Deprecation> {
+pub fn find_deprecation(diagnostic: &Handler, attrs: &[Attribute],
+                        item_sp: Span) -> Option<Deprecation> {
     find_deprecation_generic(diagnostic, attrs.iter(), item_sp)
 }
 
-pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[P<MetaItem>]) {
+pub fn require_unique_names(diagnostic: &Handler, metas: &[P<MetaItem>]) {
     let mut set = HashSet::new();
     for meta in metas {
         let name = meta.name();
@@ -702,7 +702,7 @@ pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[P<MetaItem>]) {
 /// `int_type_of_word`, below) to specify enum discriminant type; `C`, to use
 /// the same discriminant size that the corresponding C enum would or C
 /// structure layout, and `packed` to remove padding.
-pub fn find_repr_attrs(diagnostic: &SpanHandler, attr: &Attribute) -> Vec<ReprAttr> {
+pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr> {
     let mut acc = Vec::new();
     match attr.node.value.node {
         ast::MetaList(ref s, ref items) if *s == "repr" => {
index 1209c58fd5ed1abf01a440b7e2fa4d56e239f829..64b16538f05a14e0877ef28899475964ceba9b80 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use attr::AttrMetaMethods;
-use diagnostic::SpanHandler;
+use errors::Handler;
 use feature_gate::GatedCfgAttr;
 use fold::Folder;
 use {ast, fold, attr};
 /// configuration.
 struct Context<'a, F> where F: FnMut(&[ast::Attribute]) -> bool {
     in_cfg: F,
-    diagnostic: &'a SpanHandler,
+    diagnostic: &'a Handler,
 }
 
 // Support conditional compilation by transforming the AST, stripping out
 // any items that do not belong in the current configuration
-pub fn strip_unconfigured_items(diagnostic: &SpanHandler, krate: ast::Crate,
+pub fn strip_unconfigured_items(diagnostic: &Handler, krate: ast::Crate,
                                 feature_gated_cfgs: &mut Vec<GatedCfgAttr>)
                                 -> ast::Crate
 {
@@ -83,7 +83,7 @@ fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
     }
 }
 
-pub fn strip_items<'a, F>(diagnostic: &'a SpanHandler,
+pub fn strip_items<'a, F>(diagnostic: &'a Handler,
                           krate: ast::Crate, in_cfg: F) -> ast::Crate where
     F: FnMut(&[ast::Attribute]) -> bool,
 {
@@ -291,7 +291,7 @@ struct CfgAttrFolder<'a, T> {
 }
 
 // Process `#[cfg_attr]`.
-fn process_cfg_attr(diagnostic: &SpanHandler, krate: ast::Crate,
+fn process_cfg_attr(diagnostic: &Handler, krate: ast::Crate,
                     feature_gated_cfgs: &mut Vec<GatedCfgAttr>) -> ast::Crate {
     let mut fld = CfgAttrFolder {
         diag: CfgDiagReal {
@@ -463,17 +463,17 @@ fn visit_mac(&mut self, mac: &'v ast::Mac) {
 }
 
 pub trait CfgDiag {
-    fn emit_error<F>(&mut self, f: F) where F: FnMut(&SpanHandler);
+    fn emit_error<F>(&mut self, f: F) where F: FnMut(&Handler);
     fn flag_gated<F>(&mut self, f: F) where F: FnMut(&mut Vec<GatedCfgAttr>);
 }
 
 pub struct CfgDiagReal<'a, 'b> {
-    pub diag: &'a SpanHandler,
+    pub diag: &'a Handler,
     pub feature_gated_cfgs: &'b mut Vec<GatedCfgAttr>,
 }
 
 impl<'a, 'b> CfgDiag for CfgDiagReal<'a, 'b> {
-    fn emit_error<F>(&mut self, mut f: F) where F: FnMut(&SpanHandler) {
+    fn emit_error<F>(&mut self, mut f: F) where F: FnMut(&Handler) {
         f(self.diag)
     }
     fn flag_gated<F>(&mut self, mut f: F) where F: FnMut(&mut Vec<GatedCfgAttr>) {
@@ -486,7 +486,7 @@ struct CfgDiagSilent {
 }
 
 impl CfgDiag for CfgDiagSilent {
-    fn emit_error<F>(&mut self, _: F) where F: FnMut(&SpanHandler) {
+    fn emit_error<F>(&mut self, _: F) where F: FnMut(&Handler) {
         self.error = true;
     }
     fn flag_gated<F>(&mut self, _: F) where F: FnMut(&mut Vec<GatedCfgAttr>) {}
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
deleted file mode 100644 (file)
index b854a2f..0000000
+++ /dev/null
@@ -1,900 +0,0 @@
-// Copyright 2012 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.
-
-pub use self::Level::*;
-pub use self::RenderSpan::*;
-pub use self::ColorConfig::*;
-use self::Destination::*;
-
-use codemap::{self, COMMAND_LINE_SP, COMMAND_LINE_EXPN, Pos, Span};
-use diagnostics;
-
-use std::cell::{RefCell, Cell};
-use std::{cmp, error, fmt};
-use std::io::prelude::*;
-use std::io;
-use term;
-
-/// maximum number of lines we will print for each error; arbitrary.
-const MAX_LINES: usize = 6;
-
-#[derive(Clone)]
-pub enum RenderSpan {
-    /// A FullSpan renders with both with an initial line for the
-    /// message, prefixed by file:linenum, followed by a summary of
-    /// the source code covered by the span.
-    FullSpan(Span),
-
-    /// Similar to a FullSpan, but the cited position is the end of
-    /// the span, instead of the start. Used, at least, for telling
-    /// compiletest/runtest to look at the last line of the span
-    /// (since `end_highlight_lines` displays an arrow to the end
-    /// of the span).
-    EndSpan(Span),
-
-    /// A suggestion renders with both with an initial line for the
-    /// message, prefixed by file:linenum, followed by a summary
-    /// of hypothetical source code, where the `String` is spliced
-    /// into the lines in place of the code covered by the span.
-    Suggestion(Span, String),
-
-    /// A FileLine renders with just a line for the message prefixed
-    /// by file:linenum.
-    FileLine(Span),
-}
-
-impl RenderSpan {
-    fn span(&self) -> Span {
-        match *self {
-            FullSpan(s) |
-            Suggestion(s, _) |
-            EndSpan(s) |
-            FileLine(s) =>
-                s
-        }
-    }
-}
-
-#[derive(Clone, Copy)]
-pub enum ColorConfig {
-    Auto,
-    Always,
-    Never
-}
-
-pub trait Emitter {
-    fn emit(&mut self, cmsp: Option<(&codemap::CodeMap, Span)>,
-            msg: &str, code: Option<&str>, lvl: Level);
-    fn custom_emit(&mut self, cm: &codemap::CodeMap,
-                   sp: RenderSpan, msg: &str, lvl: Level);
-}
-
-/// Used as a return value to signify a fatal error occurred. (It is also
-/// used as the argument to panic at the moment, but that will eventually
-/// not be true.)
-#[derive(Copy, Clone, Debug)]
-#[must_use]
-pub struct FatalError;
-
-impl fmt::Display for FatalError {
-    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        write!(f, "parser fatal error")
-    }
-}
-
-impl error::Error for FatalError {
-    fn description(&self) -> &str {
-        "The parser has encountered a fatal error"
-    }
-}
-
-/// Signifies that the compiler died with an explicit call to `.bug`
-/// or `.span_bug` rather than a failed assertion, etc.
-#[derive(Copy, Clone, Debug)]
-pub struct ExplicitBug;
-
-impl fmt::Display for ExplicitBug {
-    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        write!(f, "parser internal bug")
-    }
-}
-
-impl error::Error for ExplicitBug {
-    fn description(&self) -> &str {
-        "The parser has encountered an internal bug"
-    }
-}
-
-/// A span-handler is like a handler but also
-/// accepts span information for source-location
-/// reporting.
-pub struct SpanHandler {
-    pub handler: Handler,
-    pub cm: codemap::CodeMap,
-}
-
-impl SpanHandler {
-    pub fn new(handler: Handler, cm: codemap::CodeMap) -> SpanHandler {
-        SpanHandler {
-            handler: handler,
-            cm: cm,
-        }
-    }
-    pub fn span_fatal(&self, sp: Span, msg: &str) -> FatalError {
-        self.handler.emit(Some((&self.cm, sp)), msg, Fatal);
-        return FatalError;
-    }
-    pub fn span_fatal_with_code(&self, sp: Span, msg: &str, code: &str) -> FatalError {
-        self.handler.emit_with_code(Some((&self.cm, sp)), msg, code, Fatal);
-        return FatalError;
-    }
-    pub fn span_err(&self, sp: Span, msg: &str) {
-        self.handler.emit(Some((&self.cm, sp)), msg, Error);
-        self.handler.bump_err_count();
-    }
-    pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
-        self.handler.emit_with_code(Some((&self.cm, sp)), msg, code, Error);
-        self.handler.bump_err_count();
-    }
-    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);
-    }
-    pub fn span_end_note(&self, sp: Span, msg: &str) {
-        self.handler.custom_emit(&self.cm, EndSpan(sp), msg, Note);
-    }
-    pub fn span_help(&self, sp: Span, msg: &str) {
-        self.handler.emit(Some((&self.cm, sp)), msg, Help);
-    }
-    /// Prints out a message with a suggested edit of the code.
-    ///
-    /// See `diagnostic::RenderSpan::Suggestion` for more information.
-    pub fn span_suggestion(&self, sp: Span, msg: &str, suggestion: String) {
-        self.handler.custom_emit(&self.cm, Suggestion(sp, suggestion), msg, Help);
-    }
-    pub fn fileline_note(&self, sp: Span, msg: &str) {
-        self.handler.custom_emit(&self.cm, FileLine(sp), msg, Note);
-    }
-    pub fn fileline_help(&self, sp: Span, msg: &str) {
-        self.handler.custom_emit(&self.cm, FileLine(sp), msg, Help);
-    }
-    pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
-        self.handler.emit(Some((&self.cm, sp)), msg, Bug);
-        panic!(ExplicitBug);
-    }
-    pub fn span_bug_no_panic(&self, sp: Span, msg: &str) {
-        self.handler.emit(Some((&self.cm, sp)), msg, Bug);
-        self.handler.bump_err_count();
-    }
-    pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! {
-        self.span_bug(sp, &format!("unimplemented {}", msg));
-    }
-    pub fn handler<'a>(&'a self) -> &'a Handler {
-        &self.handler
-    }
-}
-
-/// A handler deals with errors; certain errors
-/// (fatal, bug, unimpl) may cause immediate exit,
-/// others log errors for later reporting.
-pub struct Handler {
-    err_count: Cell<usize>,
-    emit: RefCell<Box<Emitter + Send>>,
-    pub can_emit_warnings: bool
-}
-
-impl Handler {
-    pub fn new(color_config: ColorConfig,
-               registry: Option<diagnostics::registry::Registry>,
-               can_emit_warnings: bool) -> Handler {
-        let emitter = Box::new(EmitterWriter::stderr(color_config, registry));
-        Handler::with_emitter(can_emit_warnings, emitter)
-    }
-    pub fn with_emitter(can_emit_warnings: bool, e: Box<Emitter + Send>) -> Handler {
-        Handler {
-            err_count: Cell::new(0),
-            emit: RefCell::new(e),
-            can_emit_warnings: can_emit_warnings
-        }
-    }
-    pub fn fatal(&self, msg: &str) -> FatalError {
-        self.emit.borrow_mut().emit(None, msg, None, Fatal);
-        FatalError
-    }
-    pub fn err(&self, msg: &str) {
-        self.emit.borrow_mut().emit(None, msg, None, Error);
-        self.bump_err_count();
-    }
-    pub fn bump_err_count(&self) {
-        self.err_count.set(self.err_count.get() + 1);
-    }
-    pub fn err_count(&self) -> usize {
-        self.err_count.get()
-    }
-    pub fn has_errors(&self) -> bool {
-        self.err_count.get() > 0
-    }
-    pub fn abort_if_errors(&self) {
-        let s;
-        match self.err_count.get() {
-            0 => return,
-            1 => s = "aborting due to previous error".to_string(),
-            _  => {
-                s = format!("aborting due to {} previous errors",
-                            self.err_count.get());
-            }
-        }
-
-        panic!(self.fatal(&s[..]));
-    }
-    pub fn warn(&self, msg: &str) {
-        self.emit.borrow_mut().emit(None, msg, None, Warning);
-    }
-    pub fn note(&self, msg: &str) {
-        self.emit.borrow_mut().emit(None, msg, None, Note);
-    }
-    pub fn help(&self, msg: &str) {
-        self.emit.borrow_mut().emit(None, msg, None, Help);
-    }
-    pub fn bug(&self, msg: &str) -> ! {
-        self.emit.borrow_mut().emit(None, msg, None, Bug);
-        panic!(ExplicitBug);
-    }
-    pub fn unimpl(&self, msg: &str) -> ! {
-        self.bug(&format!("unimplemented {}", msg));
-    }
-    pub fn emit(&self,
-                cmsp: Option<(&codemap::CodeMap, Span)>,
-                msg: &str,
-                lvl: Level) {
-        if lvl == Warning && !self.can_emit_warnings { return }
-        self.emit.borrow_mut().emit(cmsp, msg, None, lvl);
-    }
-    pub fn emit_with_code(&self,
-                          cmsp: Option<(&codemap::CodeMap, Span)>,
-                          msg: &str,
-                          code: &str,
-                          lvl: Level) {
-        if lvl == Warning && !self.can_emit_warnings { return }
-        self.emit.borrow_mut().emit(cmsp, msg, Some(code), lvl);
-    }
-    pub fn custom_emit(&self, cm: &codemap::CodeMap,
-                       sp: RenderSpan, msg: &str, lvl: Level) {
-        if lvl == Warning && !self.can_emit_warnings { return }
-        self.emit.borrow_mut().custom_emit(cm, sp, msg, lvl);
-    }
-}
-
-#[derive(Copy, PartialEq, Clone, Debug)]
-pub enum Level {
-    Bug,
-    Fatal,
-    Error,
-    Warning,
-    Note,
-    Help,
-}
-
-impl fmt::Display for Level {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        use std::fmt::Display;
-
-        match *self {
-            Bug => "error: internal compiler error".fmt(f),
-            Fatal | Error => "error".fmt(f),
-            Warning => "warning".fmt(f),
-            Note => "note".fmt(f),
-            Help => "help".fmt(f),
-        }
-    }
-}
-
-impl Level {
-    fn color(self) -> term::color::Color {
-        match self {
-            Bug | Fatal | Error => term::color::BRIGHT_RED,
-            Warning => term::color::BRIGHT_YELLOW,
-            Note => term::color::BRIGHT_GREEN,
-            Help => term::color::BRIGHT_CYAN,
-        }
-    }
-}
-
-pub struct EmitterWriter {
-    dst: Destination,
-    registry: Option<diagnostics::registry::Registry>
-}
-
-enum Destination {
-    Terminal(Box<term::StderrTerminal>),
-    Raw(Box<Write + Send>),
-}
-
-/// Do not use this for messages that end in `\n` – use `println_maybe_styled` instead. See
-/// `EmitterWriter::print_maybe_styled` for details.
-macro_rules! print_maybe_styled {
-    ($writer: expr, $style: expr, $($arg: tt)*) => {
-        $writer.print_maybe_styled(format_args!($($arg)*), $style, false)
-    }
-}
-
-macro_rules! println_maybe_styled {
-    ($writer: expr, $style: expr, $($arg: tt)*) => {
-        $writer.print_maybe_styled(format_args!($($arg)*), $style, true)
-    }
-}
-
-impl EmitterWriter {
-    pub fn stderr(color_config: ColorConfig,
-                  registry: Option<diagnostics::registry::Registry>) -> EmitterWriter {
-        let stderr = io::stderr();
-
-        let use_color = match color_config {
-            Always => true,
-            Never  => false,
-            Auto   => stderr_isatty(),
-        };
-
-        if use_color {
-            let dst = match term::stderr() {
-                Some(t) => Terminal(t),
-                None    => Raw(Box::new(stderr)),
-            };
-            EmitterWriter { dst: dst, registry: registry }
-        } else {
-            EmitterWriter { dst: Raw(Box::new(stderr)), registry: registry }
-        }
-    }
-
-    pub fn new(dst: Box<Write + Send>,
-               registry: Option<diagnostics::registry::Registry>) -> EmitterWriter {
-        EmitterWriter { dst: Raw(dst), registry: registry }
-    }
-
-    fn print_maybe_styled(&mut self,
-                          args: fmt::Arguments,
-                          color: term::Attr,
-                          print_newline_at_end: bool) -> io::Result<()> {
-        match self.dst {
-            Terminal(ref mut t) => {
-                try!(t.attr(color));
-                // If `msg` ends in a newline, we need to reset the color before
-                // the newline. We're making the assumption that we end up writing
-                // to a `LineBufferedWriter`, which means that emitting the reset
-                // after the newline ends up buffering the reset until we print
-                // another line or exit. Buffering the reset is a problem if we're
-                // sharing the terminal with any other programs (e.g. other rustc
-                // instances via `make -jN`).
-                //
-                // Note that if `msg` contains any internal newlines, this will
-                // result in the `LineBufferedWriter` flushing twice instead of
-                // once, which still leaves the opportunity for interleaved output
-                // to be miscolored. We assume this is rare enough that we don't
-                // have to worry about it.
-                try!(t.write_fmt(args));
-                try!(t.reset());
-                if print_newline_at_end {
-                    t.write_all(b"\n")
-                } else {
-                    Ok(())
-                }
-            }
-            Raw(ref mut w) => {
-                try!(w.write_fmt(args));
-                if print_newline_at_end {
-                    w.write_all(b"\n")
-                } else {
-                    Ok(())
-                }
-            }
-        }
-    }
-
-    fn print_diagnostic(&mut self, topic: &str, lvl: Level,
-                        msg: &str, code: Option<&str>) -> io::Result<()> {
-        if !topic.is_empty() {
-            try!(write!(&mut self.dst, "{} ", topic));
-        }
-
-        try!(print_maybe_styled!(self, term::Attr::ForegroundColor(lvl.color()),
-                                 "{}: ", lvl.to_string()));
-        try!(print_maybe_styled!(self, term::Attr::Bold, "{}", msg));
-
-        match code {
-            Some(code) => {
-                let style = term::Attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
-                try!(print_maybe_styled!(self, style, " [{}]", code.clone()));
-            }
-            None => ()
-        }
-        try!(write!(&mut self.dst, "\n"));
-        Ok(())
-    }
-
-    fn emit_(&mut self, cm: &codemap::CodeMap, rsp: RenderSpan,
-             msg: &str, code: Option<&str>, lvl: Level) -> io::Result<()> {
-        let sp = rsp.span();
-
-        // We cannot check equality directly with COMMAND_LINE_SP
-        // since PartialEq is manually implemented to ignore the ExpnId
-        let ss = if sp.expn_id == COMMAND_LINE_EXPN {
-            "<command line option>".to_string()
-        } else if let EndSpan(_) = rsp {
-            let span_end = Span { lo: sp.hi, hi: sp.hi, expn_id: sp.expn_id};
-            cm.span_to_string(span_end)
-        } else {
-            cm.span_to_string(sp)
-        };
-
-        try!(self.print_diagnostic(&ss[..], lvl, msg, code));
-
-        match rsp {
-            FullSpan(_) => {
-                try!(self.highlight_lines(cm, sp, lvl, cm.span_to_lines(sp)));
-                try!(self.print_macro_backtrace(cm, sp));
-            }
-            EndSpan(_) => {
-                try!(self.end_highlight_lines(cm, sp, lvl, cm.span_to_lines(sp)));
-                try!(self.print_macro_backtrace(cm, sp));
-            }
-            Suggestion(_, ref suggestion) => {
-                try!(self.highlight_suggestion(cm, sp, suggestion));
-                try!(self.print_macro_backtrace(cm, sp));
-            }
-            FileLine(..) => {
-                // no source text in this case!
-            }
-        }
-
-        match code {
-            Some(code) =>
-                match self.registry.as_ref().and_then(|registry| registry.find_description(code)) {
-                    Some(_) => {
-                        try!(self.print_diagnostic(&ss[..], Help,
-                                                   &format!("run `rustc --explain {}` to see a \
-                                                             detailed explanation", code), None));
-                    }
-                    None => ()
-                },
-            None => (),
-        }
-        Ok(())
-    }
-
-    fn highlight_suggestion(&mut self,
-                            cm: &codemap::CodeMap,
-                            sp: Span,
-                            suggestion: &str)
-                            -> io::Result<()>
-    {
-        let lines = cm.span_to_lines(sp).unwrap();
-        assert!(!lines.lines.is_empty());
-
-        // To build up the result, we want to take the snippet from the first
-        // line that precedes the span, prepend that with the suggestion, and
-        // then append the snippet from the last line that trails the span.
-        let fm = &lines.file;
-
-        let first_line = &lines.lines[0];
-        let prefix = fm.get_line(first_line.line_index)
-                       .map(|l| &l[..first_line.start_col.0])
-                       .unwrap_or("");
-
-        let last_line = lines.lines.last().unwrap();
-        let suffix = fm.get_line(last_line.line_index)
-                       .map(|l| &l[last_line.end_col.0..])
-                       .unwrap_or("");
-
-        let complete = format!("{}{}{}", prefix, suggestion, suffix);
-
-        // print the suggestion without any line numbers, but leave
-        // space for them. This helps with lining up with previous
-        // snippets from the actual error being reported.
-        let fm = &*lines.file;
-        let mut lines = complete.lines();
-        for (line, line_index) in lines.by_ref().take(MAX_LINES).zip(first_line.line_index..) {
-            let elided_line_num = format!("{}", line_index+1);
-            try!(write!(&mut self.dst, "{0}:{1:2$} {3}\n",
-                        fm.name, "", elided_line_num.len(), line));
-        }
-
-        // if we elided some lines, add an ellipsis
-        if lines.next().is_some() {
-            let elided_line_num = format!("{}", first_line.line_index + MAX_LINES + 1);
-            try!(write!(&mut self.dst, "{0:1$} {0:2$} ...\n",
-                        "", fm.name.len(), elided_line_num.len()));
-        }
-
-        Ok(())
-    }
-
-    fn highlight_lines(&mut self,
-                       cm: &codemap::CodeMap,
-                       sp: Span,
-                       lvl: Level,
-                       lines: codemap::FileLinesResult)
-                       -> io::Result<()>
-    {
-        let lines = match lines {
-            Ok(lines) => lines,
-            Err(_) => {
-                try!(write!(&mut self.dst, "(internal compiler error: unprintable span)\n"));
-                return Ok(());
-            }
-        };
-
-        let fm = &*lines.file;
-
-        let line_strings: Option<Vec<&str>> =
-            lines.lines.iter()
-                       .map(|info| fm.get_line(info.line_index))
-                       .collect();
-
-        let line_strings = match line_strings {
-            None => { return Ok(()); }
-            Some(line_strings) => line_strings
-        };
-
-        // Display only the first MAX_LINES lines.
-        let all_lines = lines.lines.len();
-        let display_lines = cmp::min(all_lines, MAX_LINES);
-        let display_line_infos = &lines.lines[..display_lines];
-        let display_line_strings = &line_strings[..display_lines];
-
-        // Calculate the widest number to format evenly and fix #11715
-        assert!(display_line_infos.len() > 0);
-        let mut max_line_num = display_line_infos[display_line_infos.len() - 1].line_index + 1;
-        let mut digits = 0;
-        while max_line_num > 0 {
-            max_line_num /= 10;
-            digits += 1;
-        }
-
-        // Print the offending lines
-        for (line_info, line) in display_line_infos.iter().zip(display_line_strings) {
-            try!(write!(&mut self.dst, "{}:{:>width$} {}\n",
-                        fm.name,
-                        line_info.line_index + 1,
-                        line,
-                        width=digits));
-        }
-
-        // If we elided something, put an ellipsis.
-        if display_lines < all_lines {
-            let last_line_index = display_line_infos.last().unwrap().line_index;
-            let s = format!("{}:{} ", fm.name, last_line_index + 1);
-            try!(write!(&mut self.dst, "{0:1$}...\n", "", s.len()));
-        }
-
-        // FIXME (#3260)
-        // If there's one line at fault we can easily point to the problem
-        if lines.lines.len() == 1 {
-            let lo = cm.lookup_char_pos(sp.lo);
-            let mut digits = 0;
-            let mut num = (lines.lines[0].line_index + 1) / 10;
-
-            // how many digits must be indent past?
-            while num > 0 { num /= 10; digits += 1; }
-
-            let mut s = String::new();
-            // Skip is the number of characters we need to skip because they are
-            // part of the 'filename:line ' part of the previous line.
-            let skip = fm.name.chars().count() + digits + 3;
-            for _ in 0..skip {
-                s.push(' ');
-            }
-            if let Some(orig) = fm.get_line(lines.lines[0].line_index) {
-                let mut col = skip;
-                let mut lastc = ' ';
-                let mut iter = orig.chars().enumerate();
-                for (pos, ch) in iter.by_ref() {
-                    lastc = ch;
-                    if pos >= lo.col.to_usize() { break; }
-                    // Whenever a tab occurs on the previous line, we insert one on
-                    // the error-point-squiggly-line as well (instead of a space).
-                    // That way the squiggly line will usually appear in the correct
-                    // position.
-                    match ch {
-                        '\t' => {
-                            col += 8 - col%8;
-                            s.push('\t');
-                        },
-                        _ => {
-                            col += 1;
-                            s.push(' ');
-                        },
-                    }
-                }
-
-                try!(write!(&mut self.dst, "{}", s));
-                let mut s = String::from("^");
-                let count = match lastc {
-                    // Most terminals have a tab stop every eight columns by default
-                    '\t' => 8 - col%8,
-                    _ => 1,
-                };
-                col += count;
-                s.extend(::std::iter::repeat('~').take(count));
-
-                let hi = cm.lookup_char_pos(sp.hi);
-                if hi.col != lo.col {
-                    for (pos, ch) in iter {
-                        if pos >= hi.col.to_usize() { break; }
-                        let count = match ch {
-                            '\t' => 8 - col%8,
-                            _ => 1,
-                        };
-                        col += count;
-                        s.extend(::std::iter::repeat('~').take(count));
-                    }
-                }
-
-                if s.len() > 1 {
-                    // One extra squiggly is replaced by a "^"
-                    s.pop();
-                }
-
-                try!(println_maybe_styled!(self, term::Attr::ForegroundColor(lvl.color()),
-                                           "{}", s));
-            }
-        }
-        Ok(())
-    }
-
-    /// Here are the differences between this and the normal `highlight_lines`:
-    /// `end_highlight_lines` will always put arrow on the last byte of the
-    /// span (instead of the first byte). Also, when the span is too long (more
-    /// than 6 lines), `end_highlight_lines` will print the first line, then
-    /// dot dot dot, then last line, whereas `highlight_lines` prints the first
-    /// six lines.
-    #[allow(deprecated)]
-    fn end_highlight_lines(&mut self,
-                           cm: &codemap::CodeMap,
-                           sp: Span,
-                           lvl: Level,
-                           lines: codemap::FileLinesResult)
-                          -> io::Result<()> {
-        let lines = match lines {
-            Ok(lines) => lines,
-            Err(_) => {
-                try!(write!(&mut self.dst, "(internal compiler error: unprintable span)\n"));
-                return Ok(());
-            }
-        };
-
-        let fm = &*lines.file;
-
-        let lines = &lines.lines[..];
-        if lines.len() > MAX_LINES {
-            if let Some(line) = fm.get_line(lines[0].line_index) {
-                try!(write!(&mut self.dst, "{}:{} {}\n", fm.name,
-                            lines[0].line_index + 1, line));
-            }
-            try!(write!(&mut self.dst, "...\n"));
-            let last_line_index = lines[lines.len() - 1].line_index;
-            if let Some(last_line) = fm.get_line(last_line_index) {
-                try!(write!(&mut self.dst, "{}:{} {}\n", fm.name,
-                            last_line_index + 1, last_line));
-            }
-        } else {
-            for line_info in lines {
-                if let Some(line) = fm.get_line(line_info.line_index) {
-                    try!(write!(&mut self.dst, "{}:{} {}\n", fm.name,
-                                line_info.line_index + 1, line));
-                }
-            }
-        }
-        let last_line_start = format!("{}:{} ", fm.name, lines[lines.len()-1].line_index + 1);
-        let hi = cm.lookup_char_pos(sp.hi);
-        let skip = last_line_start.chars().count();
-        let mut s = String::new();
-        for _ in 0..skip {
-            s.push(' ');
-        }
-        if let Some(orig) = fm.get_line(lines[0].line_index) {
-            let iter = orig.chars().enumerate();
-            for (pos, ch) in iter {
-                // Span seems to use half-opened interval, so subtract 1
-                if pos >= hi.col.to_usize() - 1 { break; }
-                // Whenever a tab occurs on the previous line, we insert one on
-                // the error-point-squiggly-line as well (instead of a space).
-                // That way the squiggly line will usually appear in the correct
-                // position.
-                match ch {
-                    '\t' => s.push('\t'),
-                    _ => s.push(' '),
-                }
-            }
-        }
-        s.push('^');
-        println_maybe_styled!(self, term::Attr::ForegroundColor(lvl.color()),
-                              "{}", s)
-    }
-
-    fn print_macro_backtrace(&mut self,
-                             cm: &codemap::CodeMap,
-                             sp: Span)
-                             -> io::Result<()> {
-        let mut last_span = codemap::DUMMY_SP;
-        let mut sp_opt = Some(sp);
-
-        while let Some(sp) = sp_opt {
-            sp_opt = try!(cm.with_expn_info(sp.expn_id, |expn_info| -> io::Result<_> {
-                match expn_info {
-                    Some(ei) => {
-                        let (pre, post) = match ei.callee.format {
-                            codemap::MacroAttribute(..) => ("#[", "]"),
-                            codemap::MacroBang(..) => ("", "!"),
-                        };
-                        // Don't print recursive invocations
-                        if ei.call_site != last_span {
-                            last_span = ei.call_site;
-
-                            let mut diag_string = format!("in this expansion of {}{}{}",
-                                                          pre,
-                                                          ei.callee.name(),
-                                                          post);
-
-                            if let Some(def_site_span) = ei.callee.span {
-                                diag_string.push_str(&format!(" (defined in {})",
-                                                              cm.span_to_filename(def_site_span)));
-                            }
-
-                            try!(self.print_diagnostic(&cm.span_to_string(ei.call_site),
-                                                       Note,
-                                                       &diag_string,
-                                                       None));
-                        }
-                        Ok(Some(ei.call_site))
-                    }
-                    None => Ok(None)
-                }
-            }));
-        }
-
-        Ok(())
-    }
-}
-
-#[cfg(unix)]
-fn stderr_isatty() -> bool {
-    use libc;
-    unsafe { libc::isatty(libc::STDERR_FILENO) != 0 }
-}
-#[cfg(windows)]
-fn stderr_isatty() -> bool {
-    type DWORD = u32;
-    type BOOL = i32;
-    type HANDLE = *mut u8;
-    const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
-    extern "system" {
-        fn GetStdHandle(which: DWORD) -> HANDLE;
-        fn GetConsoleMode(hConsoleHandle: HANDLE,
-                          lpMode: *mut DWORD) -> BOOL;
-    }
-    unsafe {
-        let handle = GetStdHandle(STD_ERROR_HANDLE);
-        let mut out = 0;
-        GetConsoleMode(handle, &mut out) != 0
-    }
-}
-
-impl Write for Destination {
-    fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
-        match *self {
-            Terminal(ref mut t) => t.write(bytes),
-            Raw(ref mut w) => w.write(bytes),
-        }
-    }
-    fn flush(&mut self) -> io::Result<()> {
-        match *self {
-            Terminal(ref mut t) => t.flush(),
-            Raw(ref mut w) => w.flush(),
-        }
-    }
-}
-
-impl Emitter for EmitterWriter {
-    fn emit(&mut self,
-            cmsp: Option<(&codemap::CodeMap, Span)>,
-            msg: &str, code: Option<&str>, lvl: Level) {
-        let error = match cmsp {
-            Some((cm, COMMAND_LINE_SP)) => self.emit_(cm,
-                                                FileLine(COMMAND_LINE_SP),
-                                                msg, code, lvl),
-            Some((cm, sp)) => self.emit_(cm, FullSpan(sp), msg, code, lvl),
-            None => self.print_diagnostic("", lvl, msg, code),
-        };
-
-        match error {
-            Ok(()) => {}
-            Err(e) => panic!("failed to print diagnostics: {:?}", e),
-        }
-    }
-
-    fn custom_emit(&mut self, cm: &codemap::CodeMap,
-                   sp: RenderSpan, msg: &str, lvl: Level) {
-        match self.emit_(cm, sp, msg, None, lvl) {
-            Ok(()) => {}
-            Err(e) => panic!("failed to print diagnostics: {:?}", e),
-        }
-    }
-}
-
-pub fn expect<T, M>(diag: &SpanHandler, opt: Option<T>, msg: M) -> T where
-    M: FnOnce() -> String,
-{
-    match opt {
-        Some(t) => t,
-        None => diag.handler().bug(&msg()),
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::{EmitterWriter, Level};
-    use codemap::{mk_sp, CodeMap};
-    use std::sync::{Arc, Mutex};
-    use std::io::{self, Write};
-    use std::str::from_utf8;
-
-    // Diagnostic doesn't align properly in span where line number increases by one digit
-    #[test]
-    fn test_hilight_suggestion_issue_11715() {
-        struct Sink(Arc<Mutex<Vec<u8>>>);
-        impl Write for Sink {
-            fn write(&mut self, data: &[u8]) -> io::Result<usize> {
-                Write::write(&mut *self.0.lock().unwrap(), data)
-            }
-            fn flush(&mut self) -> io::Result<()> { Ok(()) }
-        }
-        let data = Arc::new(Mutex::new(Vec::new()));
-        let mut ew = EmitterWriter::new(Box::new(Sink(data.clone())), None);
-        let cm = CodeMap::new();
-        let content = "abcdefg
-        koksi
-        line3
-        line4
-        cinq
-        line6
-        line7
-        line8
-        line9
-        line10
-        e-lä-vän
-        tolv
-        dreizehn
-        ";
-        let file = cm.new_filemap_and_lines("dummy.txt", content);
-        let start = file.lines.borrow()[7];
-        let end = file.lines.borrow()[11];
-        let sp = mk_sp(start, end);
-        let lvl = Level::Error;
-        println!("span_to_lines");
-        let lines = cm.span_to_lines(sp);
-        println!("highlight_lines");
-        ew.highlight_lines(&cm, sp, lvl, lines).unwrap();
-        println!("done");
-        let vec = data.lock().unwrap().clone();
-        let vec: &[u8] = &vec;
-        let str = from_utf8(vec).unwrap();
-        println!("{}", str);
-        assert_eq!(str, "dummy.txt: 8         line8\n\
-                         dummy.txt: 9         line9\n\
-                         dummy.txt:10         line10\n\
-                         dummy.txt:11         e-lä-vän\n\
-                         dummy.txt:12         tolv\n");
-    }
-}
diff --git a/src/libsyntax/errors/emitter.rs b/src/libsyntax/errors/emitter.rs
new file mode 100644 (file)
index 0000000..7fef85a
--- /dev/null
@@ -0,0 +1,680 @@
+// Copyright 2012-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.
+
+use self::Destination::*;
+
+use codemap::{self, COMMAND_LINE_SP, COMMAND_LINE_EXPN, Pos, Span};
+use diagnostics;
+
+use errors::{Level, RenderSpan};
+use errors::RenderSpan::*;
+use errors::Level::*;
+
+use std::{cmp, fmt};
+use std::io::prelude::*;
+use std::io;
+use std::rc::Rc;
+use term;
+
+
+pub trait Emitter {
+    fn emit(&mut self, span: Option<Span>, msg: &str, code: Option<&str>, lvl: Level);
+    fn custom_emit(&mut self, sp: RenderSpan, msg: &str, lvl: Level);
+}
+
+/// maximum number of lines we will print for each error; arbitrary.
+const MAX_LINES: usize = 6;
+
+#[derive(Clone, Copy)]
+pub enum ColorConfig {
+    Auto,
+    Always,
+    Never,
+}
+
+impl ColorConfig {
+    fn use_color(&self) -> bool {
+        match *self {
+            ColorConfig::Always => true,
+            ColorConfig::Never  => false,
+            ColorConfig::Auto   => stderr_isatty(),
+        }
+    }
+}
+
+// A basic emitter for when we don't have access to a codemap or registry. Used
+// for reporting very early errors, etc.
+pub struct BasicEmitter {
+    dst: Destination,
+}
+
+impl Emitter for BasicEmitter {
+    fn emit(&mut self,
+            sp: Option<Span>,
+            msg: &str,
+            code: Option<&str>,
+            lvl: Level) {
+        assert!(sp.is_none(), "BasicEmitter can't handle spans");
+        if let Err(e) = print_diagnostic(&mut self.dst, "", lvl, msg, code) {
+            panic!("failed to print diagnostics: {:?}", e);
+        }
+
+    }
+
+    fn custom_emit(&mut self, _: RenderSpan, _: &str, _: Level) {
+        panic!("BasicEmitter can't handle custom_emit");
+    }
+}
+
+impl BasicEmitter {
+    pub fn stderr(color_config: ColorConfig) -> BasicEmitter {
+        if color_config.use_color() {
+            let dst = Destination::from_stderr();
+            BasicEmitter { dst: dst }
+        } else {
+            BasicEmitter { dst: Raw(Box::new(io::stderr())) }
+        }
+    }
+}
+
+pub struct EmitterWriter {
+    dst: Destination,
+    registry: Option<diagnostics::registry::Registry>,
+    cm: Rc<codemap::CodeMap>,
+}
+
+impl Emitter for EmitterWriter {
+    fn emit(&mut self,
+            sp: Option<Span>,
+            msg: &str,
+            code: Option<&str>,
+            lvl: Level) {
+        let error = match sp {
+            Some(COMMAND_LINE_SP) => self.emit_(FileLine(COMMAND_LINE_SP), msg, code, lvl),
+            Some(sp) => self.emit_(FullSpan(sp), msg, code, lvl),
+            None => print_diagnostic(&mut self.dst, "", lvl, msg, code),
+        };
+
+        if let Err(e) = error {
+            panic!("failed to print diagnostics: {:?}", e);
+        }
+    }
+
+    fn custom_emit(&mut self,
+                   sp: RenderSpan,
+                   msg: &str,
+                   lvl: Level) {
+        match self.emit_(sp, msg, None, lvl) {
+            Ok(()) => {}
+            Err(e) => panic!("failed to print diagnostics: {:?}", e),
+        }
+    }
+}
+
+/// Do not use this for messages that end in `\n` – use `println_maybe_styled` instead. See
+/// `EmitterWriter::print_maybe_styled` for details.
+macro_rules! print_maybe_styled {
+    ($dst: expr, $style: expr, $($arg: tt)*) => {
+        $dst.print_maybe_styled(format_args!($($arg)*), $style, false)
+    }
+}
+
+macro_rules! println_maybe_styled {
+    ($dst: expr, $style: expr, $($arg: tt)*) => {
+        $dst.print_maybe_styled(format_args!($($arg)*), $style, true)
+    }
+}
+
+impl EmitterWriter {
+    pub fn stderr(color_config: ColorConfig,
+                  registry: Option<diagnostics::registry::Registry>,
+                  code_map: Rc<codemap::CodeMap>)
+                  -> EmitterWriter {
+        if color_config.use_color() {
+            let dst = Destination::from_stderr();
+            EmitterWriter { dst: dst, registry: registry, cm: code_map }
+        } else {
+            EmitterWriter { dst: Raw(Box::new(io::stderr())), registry: registry, cm: code_map }
+        }
+    }
+
+    pub fn new(dst: Box<Write + Send>,
+               registry: Option<diagnostics::registry::Registry>,
+               code_map: Rc<codemap::CodeMap>)
+               -> EmitterWriter {
+        EmitterWriter { dst: Raw(dst), registry: registry, cm: code_map }
+    }
+
+    fn emit_(&mut self,
+             rsp: RenderSpan,
+             msg: &str,
+             code: Option<&str>,
+             lvl: Level)
+             -> io::Result<()> {
+        let sp = rsp.span();
+
+        // We cannot check equality directly with COMMAND_LINE_SP
+        // since PartialEq is manually implemented to ignore the ExpnId
+        let ss = if sp.expn_id == COMMAND_LINE_EXPN {
+            "<command line option>".to_string()
+        } else if let EndSpan(_) = rsp {
+            let span_end = Span { lo: sp.hi, hi: sp.hi, expn_id: sp.expn_id};
+            self.cm.span_to_string(span_end)
+        } else {
+            self.cm.span_to_string(sp)
+        };
+
+        try!(print_diagnostic(&mut self.dst, &ss[..], lvl, msg, code));
+
+        match rsp {
+            FullSpan(_) => {
+                let lines = self.cm.span_to_lines(sp);
+                try!(self.highlight_lines(sp, lvl, lines));
+                try!(self.print_macro_backtrace(sp));
+            }
+            EndSpan(_) => {
+                let lines = self.cm.span_to_lines(sp);
+                try!(self.end_highlight_lines(sp, lvl, lines));
+                try!(self.print_macro_backtrace(sp));
+            }
+            Suggestion(_, ref suggestion) => {
+                try!(self.highlight_suggestion(sp, suggestion));
+                try!(self.print_macro_backtrace(sp));
+            }
+            FileLine(..) => {
+                // no source text in this case!
+            }
+        }
+
+        match code {
+            Some(code) =>
+                match self.registry.as_ref().and_then(|registry| registry.find_description(code)) {
+                    Some(_) => {
+                        try!(print_diagnostic(&mut self.dst, &ss[..], Help,
+                                              &format!("run `rustc --explain {}` to see a \
+                                                       detailed explanation", code), None));
+                    }
+                    None => ()
+                },
+            None => (),
+        }
+        Ok(())
+    }
+
+    fn highlight_suggestion(&mut self,
+                            sp: Span,
+                            suggestion: &str)
+                            -> io::Result<()>
+    {
+        let lines = self.cm.span_to_lines(sp).unwrap();
+        assert!(!lines.lines.is_empty());
+
+        // To build up the result, we want to take the snippet from the first
+        // line that precedes the span, prepend that with the suggestion, and
+        // then append the snippet from the last line that trails the span.
+        let fm = &lines.file;
+
+        let first_line = &lines.lines[0];
+        let prefix = fm.get_line(first_line.line_index)
+                       .map(|l| &l[..first_line.start_col.0])
+                       .unwrap_or("");
+
+        let last_line = lines.lines.last().unwrap();
+        let suffix = fm.get_line(last_line.line_index)
+                       .map(|l| &l[last_line.end_col.0..])
+                       .unwrap_or("");
+
+        let complete = format!("{}{}{}", prefix, suggestion, suffix);
+
+        // print the suggestion without any line numbers, but leave
+        // space for them. This helps with lining up with previous
+        // snippets from the actual error being reported.
+        let fm = &*lines.file;
+        let mut lines = complete.lines();
+        for (line, line_index) in lines.by_ref().take(MAX_LINES).zip(first_line.line_index..) {
+            let elided_line_num = format!("{}", line_index+1);
+            try!(write!(&mut self.dst, "{0}:{1:2$} {3}\n",
+                        fm.name, "", elided_line_num.len(), line));
+        }
+
+        // if we elided some lines, add an ellipsis
+        if lines.next().is_some() {
+            let elided_line_num = format!("{}", first_line.line_index + MAX_LINES + 1);
+            try!(write!(&mut self.dst, "{0:1$} {0:2$} ...\n",
+                        "", fm.name.len(), elided_line_num.len()));
+        }
+
+        Ok(())
+    }
+
+    fn highlight_lines(&mut self,
+                       sp: Span,
+                       lvl: Level,
+                       lines: codemap::FileLinesResult)
+                       -> io::Result<()>
+    {
+        let lines = match lines {
+            Ok(lines) => lines,
+            Err(_) => {
+                try!(write!(&mut self.dst, "(internal compiler error: unprintable span)\n"));
+                return Ok(());
+            }
+        };
+
+        let fm = &*lines.file;
+
+        let line_strings: Option<Vec<&str>> =
+            lines.lines.iter()
+                       .map(|info| fm.get_line(info.line_index))
+                       .collect();
+
+        let line_strings = match line_strings {
+            None => { return Ok(()); }
+            Some(line_strings) => line_strings
+        };
+
+        // Display only the first MAX_LINES lines.
+        let all_lines = lines.lines.len();
+        let display_lines = cmp::min(all_lines, MAX_LINES);
+        let display_line_infos = &lines.lines[..display_lines];
+        let display_line_strings = &line_strings[..display_lines];
+
+        // Calculate the widest number to format evenly and fix #11715
+        assert!(display_line_infos.len() > 0);
+        let mut max_line_num = display_line_infos[display_line_infos.len() - 1].line_index + 1;
+        let mut digits = 0;
+        while max_line_num > 0 {
+            max_line_num /= 10;
+            digits += 1;
+        }
+
+        // Print the offending lines
+        for (line_info, line) in display_line_infos.iter().zip(display_line_strings) {
+            try!(write!(&mut self.dst, "{}:{:>width$} {}\n",
+                        fm.name,
+                        line_info.line_index + 1,
+                        line,
+                        width=digits));
+        }
+
+        // If we elided something, put an ellipsis.
+        if display_lines < all_lines {
+            let last_line_index = display_line_infos.last().unwrap().line_index;
+            let s = format!("{}:{} ", fm.name, last_line_index + 1);
+            try!(write!(&mut self.dst, "{0:1$}...\n", "", s.len()));
+        }
+
+        // FIXME (#3260)
+        // If there's one line at fault we can easily point to the problem
+        if lines.lines.len() == 1 {
+            let lo = self.cm.lookup_char_pos(sp.lo);
+            let mut digits = 0;
+            let mut num = (lines.lines[0].line_index + 1) / 10;
+
+            // how many digits must be indent past?
+            while num > 0 { num /= 10; digits += 1; }
+
+            let mut s = String::new();
+            // Skip is the number of characters we need to skip because they are
+            // part of the 'filename:line ' part of the previous line.
+            let skip = fm.name.chars().count() + digits + 3;
+            for _ in 0..skip {
+                s.push(' ');
+            }
+            if let Some(orig) = fm.get_line(lines.lines[0].line_index) {
+                let mut col = skip;
+                let mut lastc = ' ';
+                let mut iter = orig.chars().enumerate();
+                for (pos, ch) in iter.by_ref() {
+                    lastc = ch;
+                    if pos >= lo.col.to_usize() { break; }
+                    // Whenever a tab occurs on the previous line, we insert one on
+                    // the error-point-squiggly-line as well (instead of a space).
+                    // That way the squiggly line will usually appear in the correct
+                    // position.
+                    match ch {
+                        '\t' => {
+                            col += 8 - col%8;
+                            s.push('\t');
+                        },
+                        _ => {
+                            col += 1;
+                            s.push(' ');
+                        },
+                    }
+                }
+
+                try!(write!(&mut self.dst, "{}", s));
+                let mut s = String::from("^");
+                let count = match lastc {
+                    // Most terminals have a tab stop every eight columns by default
+                    '\t' => 8 - col%8,
+                    _ => 1,
+                };
+                col += count;
+                s.extend(::std::iter::repeat('~').take(count));
+
+                let hi = self.cm.lookup_char_pos(sp.hi);
+                if hi.col != lo.col {
+                    for (pos, ch) in iter {
+                        if pos >= hi.col.to_usize() { break; }
+                        let count = match ch {
+                            '\t' => 8 - col%8,
+                            _ => 1,
+                        };
+                        col += count;
+                        s.extend(::std::iter::repeat('~').take(count));
+                    }
+                }
+
+                if s.len() > 1 {
+                    // One extra squiggly is replaced by a "^"
+                    s.pop();
+                }
+
+                try!(println_maybe_styled!(&mut self.dst, term::Attr::ForegroundColor(lvl.color()),
+                                           "{}", s));
+            }
+        }
+        Ok(())
+    }
+
+    /// Here are the differences between this and the normal `highlight_lines`:
+    /// `end_highlight_lines` will always put arrow on the last byte of the
+    /// span (instead of the first byte). Also, when the span is too long (more
+    /// than 6 lines), `end_highlight_lines` will print the first line, then
+    /// dot dot dot, then last line, whereas `highlight_lines` prints the first
+    /// six lines.
+    #[allow(deprecated)]
+    fn end_highlight_lines(&mut self,
+                           sp: Span,
+                           lvl: Level,
+                           lines: codemap::FileLinesResult)
+                          -> io::Result<()> {
+        let lines = match lines {
+            Ok(lines) => lines,
+            Err(_) => {
+                try!(write!(&mut self.dst, "(internal compiler error: unprintable span)\n"));
+                return Ok(());
+            }
+        };
+
+        let fm = &*lines.file;
+
+        let lines = &lines.lines[..];
+        if lines.len() > MAX_LINES {
+            if let Some(line) = fm.get_line(lines[0].line_index) {
+                try!(write!(&mut self.dst, "{}:{} {}\n", fm.name,
+                            lines[0].line_index + 1, line));
+            }
+            try!(write!(&mut self.dst, "...\n"));
+            let last_line_index = lines[lines.len() - 1].line_index;
+            if let Some(last_line) = fm.get_line(last_line_index) {
+                try!(write!(&mut self.dst, "{}:{} {}\n", fm.name,
+                            last_line_index + 1, last_line));
+            }
+        } else {
+            for line_info in lines {
+                if let Some(line) = fm.get_line(line_info.line_index) {
+                    try!(write!(&mut self.dst, "{}:{} {}\n", fm.name,
+                                line_info.line_index + 1, line));
+                }
+            }
+        }
+        let last_line_start = format!("{}:{} ", fm.name, lines[lines.len()-1].line_index + 1);
+        let hi = self.cm.lookup_char_pos(sp.hi);
+        let skip = last_line_start.chars().count();
+        let mut s = String::new();
+        for _ in 0..skip {
+            s.push(' ');
+        }
+        if let Some(orig) = fm.get_line(lines[0].line_index) {
+            let iter = orig.chars().enumerate();
+            for (pos, ch) in iter {
+                // Span seems to use half-opened interval, so subtract 1
+                if pos >= hi.col.to_usize() - 1 { break; }
+                // Whenever a tab occurs on the previous line, we insert one on
+                // the error-point-squiggly-line as well (instead of a space).
+                // That way the squiggly line will usually appear in the correct
+                // position.
+                match ch {
+                    '\t' => s.push('\t'),
+                    _ => s.push(' '),
+                }
+            }
+        }
+        s.push('^');
+        println_maybe_styled!(&mut self.dst, term::Attr::ForegroundColor(lvl.color()),
+                              "{}", s)
+    }
+
+    fn print_macro_backtrace(&mut self,
+                             sp: Span)
+                             -> io::Result<()> {
+        let mut last_span = codemap::DUMMY_SP;
+        let mut span = sp;
+
+        loop {
+            let span_name_span = self.cm.with_expn_info(span.expn_id, |expn_info| {
+                expn_info.map(|ei| {
+                    let (pre, post) = match ei.callee.format {
+                        codemap::MacroAttribute(..) => ("#[", "]"),
+                        codemap::MacroBang(..) => ("", "!"),
+                    };
+                    let macro_decl_name = format!("in this expansion of {}{}{}",
+                                                  pre,
+                                                  ei.callee.name(),
+                                                  post);
+                    let def_site_span = ei.callee.span;
+                    (ei.call_site, macro_decl_name, def_site_span)
+                })
+            });
+            let (macro_decl_name, def_site_span) = match span_name_span {
+                None => break,
+                Some((sp, macro_decl_name, def_site_span)) => {
+                    span = sp;
+                    (macro_decl_name, def_site_span)
+                }
+            };
+
+            // Don't print recursive invocations
+            if span != last_span {
+                let mut diag_string = macro_decl_name;
+                if let Some(def_site_span) = def_site_span {
+                    diag_string.push_str(&format!(" (defined in {})",
+                                                  self.cm.span_to_filename(def_site_span)));
+                }
+
+                let snippet = self.cm.span_to_string(span);
+                try!(print_diagnostic(&mut self.dst, &snippet, Note, &diag_string, None));
+            }
+            last_span = span;
+        }
+
+        Ok(())
+    }
+}
+
+fn print_diagnostic(dst: &mut Destination,
+                    topic: &str,
+                    lvl: Level,
+                    msg: &str,
+                    code: Option<&str>)
+                    -> io::Result<()> {
+    if !topic.is_empty() {
+        try!(write!(dst, "{} ", topic));
+    }
+
+    try!(print_maybe_styled!(dst, term::Attr::ForegroundColor(lvl.color()),
+                             "{}: ", lvl.to_string()));
+    try!(print_maybe_styled!(dst, term::Attr::Bold, "{}", msg));
+
+    match code {
+        Some(code) => {
+            let style = term::Attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
+            try!(print_maybe_styled!(dst, style, " [{}]", code.clone()));
+        }
+        None => ()
+    }
+    try!(write!(dst, "\n"));
+    Ok(())
+}
+
+#[cfg(unix)]
+fn stderr_isatty() -> bool {
+    use libc;
+    unsafe { libc::isatty(libc::STDERR_FILENO) != 0 }
+}
+#[cfg(windows)]
+fn stderr_isatty() -> bool {
+    type DWORD = u32;
+    type BOOL = i32;
+    type HANDLE = *mut u8;
+    const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
+    extern "system" {
+        fn GetStdHandle(which: DWORD) -> HANDLE;
+        fn GetConsoleMode(hConsoleHandle: HANDLE,
+                          lpMode: *mut DWORD) -> BOOL;
+    }
+    unsafe {
+        let handle = GetStdHandle(STD_ERROR_HANDLE);
+        let mut out = 0;
+        GetConsoleMode(handle, &mut out) != 0
+    }
+}
+
+enum Destination {
+    Terminal(Box<term::StderrTerminal>),
+    Raw(Box<Write + Send>),
+}
+
+impl Destination {
+    fn from_stderr() -> Destination {
+        match term::stderr() {
+            Some(t) => Terminal(t),
+            None    => Raw(Box::new(io::stderr())),
+        }
+    }
+
+    fn print_maybe_styled(&mut self,
+                          args: fmt::Arguments,
+                          color: term::Attr,
+                          print_newline_at_end: bool)
+                          -> io::Result<()> {
+        match *self {
+            Terminal(ref mut t) => {
+                try!(t.attr(color));
+                // If `msg` ends in a newline, we need to reset the color before
+                // the newline. We're making the assumption that we end up writing
+                // to a `LineBufferedWriter`, which means that emitting the reset
+                // after the newline ends up buffering the reset until we print
+                // another line or exit. Buffering the reset is a problem if we're
+                // sharing the terminal with any other programs (e.g. other rustc
+                // instances via `make -jN`).
+                //
+                // Note that if `msg` contains any internal newlines, this will
+                // result in the `LineBufferedWriter` flushing twice instead of
+                // once, which still leaves the opportunity for interleaved output
+                // to be miscolored. We assume this is rare enough that we don't
+                // have to worry about it.
+                try!(t.write_fmt(args));
+                try!(t.reset());
+                if print_newline_at_end {
+                    t.write_all(b"\n")
+                } else {
+                    Ok(())
+                }
+            }
+            Raw(ref mut w) => {
+                try!(w.write_fmt(args));
+                if print_newline_at_end {
+                    w.write_all(b"\n")
+                } else {
+                    Ok(())
+                }
+            }
+        }
+    }
+}
+
+impl Write for Destination {
+    fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
+        match *self {
+            Terminal(ref mut t) => t.write(bytes),
+            Raw(ref mut w) => w.write(bytes),
+        }
+    }
+    fn flush(&mut self) -> io::Result<()> {
+        match *self {
+            Terminal(ref mut t) => t.flush(),
+            Raw(ref mut w) => w.flush(),
+        }
+    }
+}
+
+
+#[cfg(test)]
+mod test {
+    use errors::Level;
+    use super::EmitterWriter;
+    use codemap::{mk_sp, CodeMap};
+    use std::sync::{Arc, Mutex};
+    use std::io::{self, Write};
+    use std::str::from_utf8;
+    use std::rc::Rc;
+
+    // Diagnostic doesn't align properly in span where line number increases by one digit
+    #[test]
+    fn test_hilight_suggestion_issue_11715() {
+        struct Sink(Arc<Mutex<Vec<u8>>>);
+        impl Write for Sink {
+            fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+                Write::write(&mut *self.0.lock().unwrap(), data)
+            }
+            fn flush(&mut self) -> io::Result<()> { Ok(()) }
+        }
+        let data = Arc::new(Mutex::new(Vec::new()));
+        let cm = Rc::new(CodeMap::new());
+        let mut ew = EmitterWriter::new(Box::new(Sink(data.clone())), None, cm.clone());
+        let content = "abcdefg
+        koksi
+        line3
+        line4
+        cinq
+        line6
+        line7
+        line8
+        line9
+        line10
+        e-lä-vän
+        tolv
+        dreizehn
+        ";
+        let file = cm.new_filemap_and_lines("dummy.txt", content);
+        let start = file.lines.borrow()[7];
+        let end = file.lines.borrow()[11];
+        let sp = mk_sp(start, end);
+        let lvl = Level::Error;
+        println!("span_to_lines");
+        let lines = cm.span_to_lines(sp);
+        println!("highlight_lines");
+        ew.highlight_lines(sp, lvl, lines).unwrap();
+        println!("done");
+        let vec = data.lock().unwrap().clone();
+        let vec: &[u8] = &vec;
+        let str = from_utf8(vec).unwrap();
+        println!("{}", str);
+        assert_eq!(str, "dummy.txt: 8         line8\n\
+                         dummy.txt: 9         line9\n\
+                         dummy.txt:10         line10\n\
+                         dummy.txt:11         e-lä-vän\n\
+                         dummy.txt:12         tolv\n");
+    }
+}
diff --git a/src/libsyntax/errors/mod.rs b/src/libsyntax/errors/mod.rs
new file mode 100644 (file)
index 0000000..f2e6109
--- /dev/null
@@ -0,0 +1,338 @@
+// Copyright 2012-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.
+
+pub use errors::emitter::ColorConfig;
+
+use self::Level::*;
+use self::RenderSpan::*;
+
+use codemap::{self, Span};
+use diagnostics;
+use errors::emitter::{Emitter, EmitterWriter};
+
+use std::cell::{RefCell, Cell};
+use std::{error, fmt};
+use std::io::prelude::*;
+use std::rc::Rc;
+use term;
+
+pub mod emitter;
+
+#[derive(Clone)]
+pub enum RenderSpan {
+    /// A FullSpan renders with both with an initial line for the
+    /// message, prefixed by file:linenum, followed by a summary of
+    /// the source code covered by the span.
+    FullSpan(Span),
+
+    /// Similar to a FullSpan, but the cited position is the end of
+    /// the span, instead of the start. Used, at least, for telling
+    /// compiletest/runtest to look at the last line of the span
+    /// (since `end_highlight_lines` displays an arrow to the end
+    /// of the span).
+    EndSpan(Span),
+
+    /// A suggestion renders with both with an initial line for the
+    /// message, prefixed by file:linenum, followed by a summary
+    /// of hypothetical source code, where the `String` is spliced
+    /// into the lines in place of the code covered by the span.
+    Suggestion(Span, String),
+
+    /// A FileLine renders with just a line for the message prefixed
+    /// by file:linenum.
+    FileLine(Span),
+}
+
+impl RenderSpan {
+    fn span(&self) -> Span {
+        match *self {
+            FullSpan(s) |
+            Suggestion(s, _) |
+            EndSpan(s) |
+            FileLine(s) =>
+                s
+        }
+    }
+}
+
+/// Used as a return value to signify a fatal error occurred. (It is also
+/// used as the argument to panic at the moment, but that will eventually
+/// not be true.)
+#[derive(Copy, Clone, Debug)]
+#[must_use]
+pub struct FatalError;
+
+impl fmt::Display for FatalError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+        write!(f, "parser fatal error")
+    }
+}
+
+impl error::Error for FatalError {
+    fn description(&self) -> &str {
+        "The parser has encountered a fatal error"
+    }
+}
+
+/// Signifies that the compiler died with an explicit call to `.bug`
+/// or `.span_bug` rather than a failed assertion, etc.
+#[derive(Copy, Clone, Debug)]
+pub struct ExplicitBug;
+
+impl fmt::Display for ExplicitBug {
+    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+        write!(f, "parser internal bug")
+    }
+}
+
+impl error::Error for ExplicitBug {
+    fn description(&self) -> &str {
+        "The parser has encountered an internal bug"
+    }
+}
+
+/// A handler deals with errors; certain errors
+/// (fatal, bug, unimpl) may cause immediate exit,
+/// others log errors for later reporting.
+pub struct Handler {
+    err_count: Cell<usize>,
+    emit: RefCell<Box<Emitter>>,
+    pub can_emit_warnings: bool,
+    treat_err_as_bug: bool,
+    delayed_span_bug: RefCell<Option<(codemap::Span, String)>>,
+}
+
+impl Handler {
+    pub fn new(color_config: ColorConfig,
+               registry: Option<diagnostics::registry::Registry>,
+               can_emit_warnings: bool,
+               treat_err_as_bug: bool,
+               cm: Rc<codemap::CodeMap>)
+               -> Handler {
+        let emitter = Box::new(EmitterWriter::stderr(color_config, registry, cm));
+        Handler::with_emitter(can_emit_warnings, treat_err_as_bug, emitter)
+    }
+
+    pub fn with_emitter(can_emit_warnings: bool,
+                        treat_err_as_bug: bool,
+                        e: Box<Emitter>) -> Handler {
+        Handler {
+            err_count: Cell::new(0),
+            emit: RefCell::new(e),
+            can_emit_warnings: can_emit_warnings,
+            treat_err_as_bug: treat_err_as_bug,
+            delayed_span_bug: RefCell::new(None),
+        }
+    }
+
+    pub fn span_fatal(&self, sp: Span, msg: &str) -> FatalError {
+        if self.treat_err_as_bug {
+            self.span_bug(sp, msg);
+        }
+        self.emit(Some(sp), msg, Fatal);
+        return FatalError;
+    }
+    pub fn span_fatal_with_code(&self, sp: Span, msg: &str, code: &str) -> FatalError {
+        if self.treat_err_as_bug {
+            self.span_bug(sp, msg);
+        }
+        self.emit_with_code(Some(sp), msg, code, Fatal);
+        return FatalError;
+    }
+    pub fn span_err(&self, sp: Span, msg: &str) {
+        if self.treat_err_as_bug {
+            self.span_bug(sp, msg);
+        }
+        self.emit(Some(sp), msg, Error);
+        self.bump_err_count();
+    }
+    pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
+        if self.treat_err_as_bug {
+            self.span_bug(sp, msg);
+        }
+        self.emit_with_code(Some(sp), msg, code, Error);
+        self.bump_err_count();
+    }
+    pub fn span_warn(&self, sp: Span, msg: &str) {
+        self.emit(Some(sp), msg, Warning);
+    }
+    pub fn span_warn_with_code(&self, sp: Span, msg: &str, code: &str) {
+        self.emit_with_code(Some(sp), msg, code, Warning);
+    }
+    pub fn span_note(&self, sp: Span, msg: &str) {
+        self.emit(Some(sp), msg, Note);
+    }
+    pub fn span_end_note(&self, sp: Span, msg: &str) {
+        self.custom_emit(EndSpan(sp), msg, Note);
+    }
+    pub fn span_help(&self, sp: Span, msg: &str) {
+        self.emit(Some(sp), msg, Help);
+    }
+    /// Prints out a message with a suggested edit of the code.
+    ///
+    /// See `diagnostic::RenderSpan::Suggestion` for more information.
+    pub fn span_suggestion(&self, sp: Span, msg: &str, suggestion: String) {
+        self.custom_emit(Suggestion(sp, suggestion), msg, Help);
+    }
+    pub fn fileline_note(&self, sp: Span, msg: &str) {
+        self.custom_emit(FileLine(sp), msg, Note);
+    }
+    pub fn fileline_help(&self, sp: Span, msg: &str) {
+        self.custom_emit(FileLine(sp), msg, Help);
+    }
+    pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
+        self.emit(Some(sp), msg, Bug);
+        panic!(ExplicitBug);
+    }
+    pub fn delay_span_bug(&self, sp: Span, msg: &str) {
+        let mut delayed = self.delayed_span_bug.borrow_mut();
+        *delayed = Some((sp, msg.to_string()));
+    }
+    pub fn span_bug_no_panic(&self, sp: Span, msg: &str) {
+        self.emit(Some(sp), msg, Bug);
+        self.bump_err_count();
+    }
+    pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! {
+        self.span_bug(sp, &format!("unimplemented {}", msg));
+    }
+    pub fn fatal(&self, msg: &str) -> FatalError {
+        if self.treat_err_as_bug {
+            self.bug(msg);
+        }
+        self.emit.borrow_mut().emit(None, msg, None, Fatal);
+        FatalError
+    }
+    pub fn err(&self, msg: &str) {
+        if self.treat_err_as_bug {
+            self.bug(msg);
+        }
+        self.emit.borrow_mut().emit(None, msg, None, Error);
+        self.bump_err_count();
+    }
+    pub fn warn(&self, msg: &str) {
+        self.emit.borrow_mut().emit(None, msg, None, Warning);
+    }
+    pub fn note(&self, msg: &str) {
+        self.emit.borrow_mut().emit(None, msg, None, Note);
+    }
+    pub fn help(&self, msg: &str) {
+        self.emit.borrow_mut().emit(None, msg, None, Help);
+    }
+    pub fn bug(&self, msg: &str) -> ! {
+        self.emit.borrow_mut().emit(None, msg, None, Bug);
+        panic!(ExplicitBug);
+    }
+    pub fn unimpl(&self, msg: &str) -> ! {
+        self.bug(&format!("unimplemented {}", msg));
+    }
+
+    pub fn bump_err_count(&self) {
+        self.err_count.set(self.err_count.get() + 1);
+    }
+
+    pub fn err_count(&self) -> usize {
+        self.err_count.get()
+    }
+
+    pub fn has_errors(&self) -> bool {
+        self.err_count.get() > 0
+    }
+
+    pub fn abort_if_errors(&self) {
+        let s;
+        match self.err_count.get() {
+            0 => {
+                let delayed_bug = self.delayed_span_bug.borrow();
+                match *delayed_bug {
+                    Some((span, ref errmsg)) => {
+                        self.span_bug(span, errmsg);
+                    },
+                    _ => {}
+                }
+
+                return;
+            }
+            1 => s = "aborting due to previous error".to_string(),
+            _  => {
+                s = format!("aborting due to {} previous errors",
+                            self.err_count.get());
+            }
+        }
+
+        panic!(self.fatal(&s[..]));
+    }
+
+    pub fn emit(&self,
+                sp: Option<Span>,
+                msg: &str,
+                lvl: Level) {
+        if lvl == Warning && !self.can_emit_warnings { return }
+        self.emit.borrow_mut().emit(sp, msg, None, lvl);
+    }
+
+    pub fn emit_with_code(&self,
+                          sp: Option<Span>,
+                          msg: &str,
+                          code: &str,
+                          lvl: Level) {
+        if lvl == Warning && !self.can_emit_warnings { return }
+        self.emit.borrow_mut().emit(sp, msg, Some(code), lvl);
+    }
+
+    pub fn custom_emit(&self, sp: RenderSpan, msg: &str, lvl: Level) {
+        if lvl == Warning && !self.can_emit_warnings { return }
+        self.emit.borrow_mut().custom_emit(sp, msg, lvl);
+    }
+}
+
+
+#[derive(Copy, PartialEq, Clone, Debug)]
+pub enum Level {
+    Bug,
+    Fatal,
+    Error,
+    Warning,
+    Note,
+    Help,
+}
+
+impl fmt::Display for Level {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        use std::fmt::Display;
+
+        match *self {
+            Bug => "error: internal compiler error".fmt(f),
+            Fatal | Error => "error".fmt(f),
+            Warning => "warning".fmt(f),
+            Note => "note".fmt(f),
+            Help => "help".fmt(f),
+        }
+    }
+}
+
+impl Level {
+    fn color(self) -> term::color::Color {
+        match self {
+            Bug | Fatal | Error => term::color::BRIGHT_RED,
+            Warning => term::color::BRIGHT_YELLOW,
+            Note => term::color::BRIGHT_GREEN,
+            Help => term::color::BRIGHT_CYAN,
+        }
+    }
+}
+
+pub fn expect<T, M>(diag: &Handler, opt: Option<T>, msg: M) -> T where
+    M: FnOnce() -> String,
+{
+    match opt {
+        Some(t) => t,
+        None => diag.bug(&msg()),
+    }
+}
index 9d62e407cb9135ae445bbe9a676250092c07e6d1..f198460137d5f78f070af026c1c63e66c45d90be 100644 (file)
@@ -720,7 +720,7 @@ pub fn fileline_help(&self, sp: Span, msg: &str) {
         self.parse_sess.span_diagnostic.fileline_help(sp, msg);
     }
     pub fn bug(&self, msg: &str) -> ! {
-        self.parse_sess.span_diagnostic.handler().bug(msg);
+        self.parse_sess.span_diagnostic.bug(msg);
     }
     pub fn trace_macros(&self) -> bool {
         self.ecfg.trace_mac
index cdc9cb024530d8b578f6ca483fd897913fae49fc..46a39b98058a2382a9387b9849edb1407a60ec20 100644 (file)
@@ -14,7 +14,6 @@
 use attr;
 use codemap::{Span, respan, Spanned, DUMMY_SP, Pos};
 use ext::base::ExtCtxt;
-use owned_slice::OwnedSlice;
 use parse::token::special_idents;
 use parse::token::InternedString;
 use parse::token;
@@ -56,7 +55,7 @@ fn qpath_all(&self, self_type: P<ast::Ty>,
 
     fn ty(&self, span: Span, ty: ast::Ty_) -> P<ast::Ty>;
     fn ty_path(&self, ast::Path) -> P<ast::Ty>;
-    fn ty_sum(&self, ast::Path, OwnedSlice<ast::TyParamBound>) -> P<ast::Ty>;
+    fn ty_sum(&self, ast::Path, ast::TyParamBounds) -> P<ast::Ty>;
     fn ty_ident(&self, span: Span, idents: ast::Ident) -> P<ast::Ty>;
 
     fn ty_rptr(&self, span: Span,
@@ -70,13 +69,13 @@ fn ty_ptr(&self, span: Span,
     fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty>;
     fn ty_infer(&self, sp: Span) -> P<ast::Ty>;
 
-    fn ty_vars(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> ;
-    fn ty_vars_global(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> ;
+    fn ty_vars(&self, ty_params: &P<[ast::TyParam]>) -> Vec<P<ast::Ty>> ;
+    fn ty_vars_global(&self, ty_params: &P<[ast::TyParam]>) -> Vec<P<ast::Ty>> ;
 
     fn typaram(&self,
                span: Span,
                id: ast::Ident,
-               bounds: OwnedSlice<ast::TyParamBound>,
+               bounds: ast::TyParamBounds,
                default: Option<P<ast::Ty>>) -> ast::TyParam;
 
     fn trait_ref(&self, path: ast::Path) -> ast::TraitRef;
@@ -331,8 +330,8 @@ fn path_all(&self,
             identifier: last_identifier,
             parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
                 lifetimes: lifetimes,
-                types: OwnedSlice::from_vec(types),
-                bindings: OwnedSlice::from_vec(bindings),
+                types: P::from_vec(types),
+                bindings: P::from_vec(bindings),
             })
         });
         ast::Path {
@@ -369,8 +368,8 @@ fn qpath_all(&self,
             identifier: ident,
             parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
                 lifetimes: lifetimes,
-                types: OwnedSlice::from_vec(types),
-                bindings: OwnedSlice::from_vec(bindings),
+                types: P::from_vec(types),
+                bindings: P::from_vec(bindings),
             })
         });
 
@@ -399,7 +398,7 @@ fn ty_path(&self, path: ast::Path) -> P<ast::Ty> {
         self.ty(path.span, ast::TyPath(None, path))
     }
 
-    fn ty_sum(&self, path: ast::Path, bounds: OwnedSlice<ast::TyParamBound>) -> P<ast::Ty> {
+    fn ty_sum(&self, path: ast::Path, bounds: ast::TyParamBounds) -> P<ast::Ty> {
         self.ty(path.span,
                 ast::TyObjectSum(self.ty_path(path),
                                  bounds))
@@ -448,7 +447,7 @@ fn ty_infer(&self, span: Span) -> P<ast::Ty> {
     fn typaram(&self,
                span: Span,
                id: ast::Ident,
-               bounds: OwnedSlice<ast::TyParamBound>,
+               bounds: ast::TyParamBounds,
                default: Option<P<ast::Ty>>) -> ast::TyParam {
         ast::TyParam {
             ident: id,
@@ -462,11 +461,11 @@ fn typaram(&self,
     // these are strange, and probably shouldn't be used outside of
     // pipes. Specifically, the global version possible generates
     // incorrect code.
-    fn ty_vars(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> {
+    fn ty_vars(&self, ty_params: &P<[ast::TyParam]>) -> Vec<P<ast::Ty>> {
         ty_params.iter().map(|p| self.ty_ident(DUMMY_SP, p.ident)).collect()
     }
 
-    fn ty_vars_global(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> {
+    fn ty_vars_global(&self, ty_params: &P<[ast::TyParam]>) -> Vec<P<ast::Ty>> {
         ty_params
             .iter()
             .map(|p| self.ty_path(self.path_global(DUMMY_SP, vec!(p.ident))))
index 02d318e5b533744d2f6fcd98289f14803ef5d82c..743bcda18def441507ef0cd3a3f1ca4a2995b32e 100644 (file)
@@ -1301,7 +1301,7 @@ pub fn expand_crate(mut cx: ExtCtxt,
 
         let mut ret = expander.fold_crate(c);
         ret.exported_macros = expander.cx.exported_macros.clone();
-        cx.parse_sess.span_diagnostic.handler().abort_if_errors();
+        cx.parse_sess.span_diagnostic.abort_if_errors();
         ret
     };
     return (ret, cx.syntax_env.names);
index d5993c81f241123bdec078f27d8fa42302b15ff0..8878c606d6a2c80a0c4b86b1d956adf50511308d 100644 (file)
@@ -12,7 +12,7 @@
 use ast;
 use ast::{TokenTree, Ident, Name};
 use codemap::{Span, DUMMY_SP};
-use diagnostic::SpanHandler;
+use errors::Handler;
 use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
 use parse::token::{DocComment, MatchNt, SubstNt};
 use parse::token::{Token, NtIdent, SpecialMacroVar};
@@ -34,7 +34,7 @@ struct TtFrame {
 
 #[derive(Clone)]
 pub struct TtReader<'a> {
-    pub sp_diag: &'a SpanHandler,
+    pub sp_diag: &'a Handler,
     /// the unzipped tree:
     stack: Vec<TtFrame>,
     /* for MBE-style macro transcription */
@@ -55,7 +55,7 @@ pub struct TtReader<'a> {
 /// This can do Macro-By-Example transcription. On the other hand, if
 /// `src` contains no `TokenTree::Sequence`s, `MatchNt`s or `SubstNt`s, `interp` can
 /// (and should) be None.
-pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
+pub fn new_tt_reader<'a>(sp_diag: &'a Handler,
                          interp: Option<HashMap<Name, Rc<NamedMatch>>>,
                          imported_from: Option<Ident>,
                          src: Vec<ast::TokenTree>)
@@ -69,7 +69,7 @@ pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
 /// This can do Macro-By-Example transcription. On the other hand, if
 /// `src` contains no `TokenTree::Sequence`s, `MatchNt`s or `SubstNt`s, `interp` can
 /// (and should) be None.
-pub fn new_tt_reader_with_doc_flag<'a>(sp_diag: &'a SpanHandler,
+pub fn new_tt_reader_with_doc_flag<'a>(sp_diag: &'a Handler,
                                        interp: Option<HashMap<Name, Rc<NamedMatch>>>,
                                        imported_from: Option<Ident>,
                                        src: Vec<ast::TokenTree>,
index f186aff6d363ac40516cd227a1b10bb5f542986e..89f318d09451b8b56c4890ce54bc9346ee1e525a 100644 (file)
@@ -32,7 +32,7 @@
 use attr;
 use attr::AttrMetaMethods;
 use codemap::{CodeMap, Span};
-use diagnostic::SpanHandler;
+use errors::Handler;
 use visit;
 use visit::{FnKind, Visitor};
 use parse::token::InternedString;
@@ -446,7 +446,7 @@ fn partial_cmp(&self, other: &GatedCfgAttr) -> Option<cmp::Ordering> {
 }
 
 impl GatedCfgAttr {
-    pub fn check_and_emit(&self, diagnostic: &SpanHandler, features: &Features) {
+    pub fn check_and_emit(&self, diagnostic: &Handler, features: &Features) {
         match *self {
             GatedCfgAttr::GatedCfg(ref cfg) => {
                 cfg.check_and_emit(diagnostic, features);
@@ -476,7 +476,7 @@ pub fn gate(cfg: &ast::MetaItem) -> Option<GatedCfg> {
                       }
                   })
     }
-    fn check_and_emit(&self, diagnostic: &SpanHandler, features: &Features) {
+    fn check_and_emit(&self, diagnostic: &Handler, features: &Features) {
         let (cfg, feature, has_feature) = GATED_CFGS[self.index];
         if !has_feature(features) {
             let explain = format!("`cfg({})` is experimental and subject to change", cfg);
@@ -595,21 +595,21 @@ pub fn new() -> Features {
 const EXPLAIN_STMT_ATTR_SYNTAX: &'static str =
     "attributes on non-item statements and expressions are experimental.";
 
-pub fn check_for_box_syntax(f: Option<&Features>, diag: &SpanHandler, span: Span) {
+pub fn check_for_box_syntax(f: Option<&Features>, diag: &Handler, span: Span) {
     if let Some(&Features { allow_box: true, .. }) = f {
         return;
     }
     emit_feature_err(diag, "box_syntax", span, GateIssue::Language, EXPLAIN_BOX_SYNTAX);
 }
 
-pub fn check_for_placement_in(f: Option<&Features>, diag: &SpanHandler, span: Span) {
+pub fn check_for_placement_in(f: Option<&Features>, diag: &Handler, span: Span) {
     if let Some(&Features { allow_placement_in: true, .. }) = f {
         return;
     }
     emit_feature_err(diag, "placement_in_syntax", span, GateIssue::Language, EXPLAIN_PLACEMENT_IN);
 }
 
-pub fn check_for_pushpop_syntax(f: Option<&Features>, diag: &SpanHandler, span: Span) {
+pub fn check_for_pushpop_syntax(f: Option<&Features>, diag: &Handler, span: Span) {
     if let Some(&Features { allow_pushpop_unsafe: true, .. }) = f {
         return;
     }
@@ -618,7 +618,7 @@ pub fn check_for_pushpop_syntax(f: Option<&Features>, diag: &SpanHandler, span:
 
 struct Context<'a> {
     features: Vec<&'static str>,
-    span_handler: &'a SpanHandler,
+    span_handler: &'a Handler,
     cm: &'a CodeMap,
     plugin_attributes: &'a [(String, AttributeType)],
 }
@@ -704,7 +704,7 @@ pub enum GateIssue {
     Library(Option<u32>)
 }
 
-pub fn emit_feature_err(diag: &SpanHandler, feature: &str, span: Span, issue: GateIssue,
+pub fn emit_feature_err(diag: &Handler, feature: &str, span: Span, issue: GateIssue,
                         explain: &str) {
     let issue = match issue {
         GateIssue::Language => find_lang_feature_issue(feature),
@@ -1064,7 +1064,7 @@ fn visit_impl_item(&mut self, ii: &'v ast::ImplItem) {
     }
 }
 
-fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
+fn check_crate_inner<F>(cm: &CodeMap, span_handler: &Handler,
                         krate: &ast::Crate,
                         plugin_attributes: &[(String, AttributeType)],
                         check: F)
@@ -1161,13 +1161,13 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
     }
 }
 
-pub fn check_crate_macros(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate)
+pub fn check_crate_macros(cm: &CodeMap, span_handler: &Handler, krate: &ast::Crate)
 -> Features {
     check_crate_inner(cm, span_handler, krate, &[] as &'static [_],
                       |ctx, krate| visit::walk_crate(&mut MacroVisitor { context: ctx }, krate))
 }
 
-pub fn check_crate(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate,
+pub fn check_crate(cm: &CodeMap, span_handler: &Handler, krate: &ast::Crate,
                    plugin_attributes: &[(String, AttributeType)],
                    unstable: UnstableFeatures) -> Features
 {
@@ -1192,7 +1192,7 @@ pub enum UnstableFeatures {
     Cheat
 }
 
-fn maybe_stage_features(span_handler: &SpanHandler, krate: &ast::Crate,
+fn maybe_stage_features(span_handler: &Handler, krate: &ast::Crate,
                         unstable: UnstableFeatures) {
     let allow_features = match unstable {
         UnstableFeatures::Allow => true,
index cd976884d2fadc97c31ba7eac31be615f98a2fc8..cd2210c71b89539c3420f305fccebe6c323f8664 100644 (file)
@@ -23,7 +23,6 @@
 use attr::{ThinAttributes, ThinAttributesExt};
 use ast_util;
 use codemap::{respan, Span, Spanned};
-use owned_slice::OwnedSlice;
 use parse::token;
 use ptr::P;
 use util::small_vector::SmallVector;
@@ -233,7 +232,7 @@ fn fold_ty_param(&mut self, tp: TyParam) -> TyParam {
         noop_fold_ty_param(tp, self)
     }
 
-    fn fold_ty_params(&mut self, tps: OwnedSlice<TyParam>) -> OwnedSlice<TyParam> {
+    fn fold_ty_params(&mut self, tps: P<[TyParam]>) -> P<[TyParam]> {
         noop_fold_ty_params(tps, self)
     }
 
@@ -257,13 +256,13 @@ fn fold_opt_lifetime(&mut self, o_lt: Option<Lifetime>) -> Option<Lifetime> {
         noop_fold_opt_lifetime(o_lt, self)
     }
 
-    fn fold_opt_bounds(&mut self, b: Option<OwnedSlice<TyParamBound>>)
-                       -> Option<OwnedSlice<TyParamBound>> {
+    fn fold_opt_bounds(&mut self, b: Option<TyParamBounds>)
+                       -> Option<TyParamBounds> {
         noop_fold_opt_bounds(b, self)
     }
 
-    fn fold_bounds(&mut self, b: OwnedSlice<TyParamBound>)
-                       -> OwnedSlice<TyParamBound> {
+    fn fold_bounds(&mut self, b: TyParamBounds)
+                       -> TyParamBounds {
         noop_fold_bounds(b, self)
     }
 
@@ -714,8 +713,8 @@ pub fn noop_fold_ty_param<T: Folder>(tp: TyParam, fld: &mut T) -> TyParam {
     }
 }
 
-pub fn noop_fold_ty_params<T: Folder>(tps: OwnedSlice<TyParam>, fld: &mut T)
-                                      -> OwnedSlice<TyParam> {
+pub fn noop_fold_ty_params<T: Folder>(tps: P<[TyParam]>, fld: &mut T)
+                                      -> P<[TyParam]> {
     tps.move_map(|tp| fld.fold_ty_param(tp))
 }
 
@@ -871,8 +870,8 @@ pub fn noop_fold_mt<T: Folder>(MutTy {ty, mutbl}: MutTy, folder: &mut T) -> MutT
     }
 }
 
-pub fn noop_fold_opt_bounds<T: Folder>(b: Option<OwnedSlice<TyParamBound>>, folder: &mut T)
-                                       -> Option<OwnedSlice<TyParamBound>> {
+pub fn noop_fold_opt_bounds<T: Folder>(b: Option<TyParamBounds>, folder: &mut T)
+                                       -> Option<TyParamBounds> {
     b.map(|bounds| folder.fold_bounds(bounds))
 }
 
index 73d7025b4f155da5c197e14107c9021f541fa76d..47340d312242b2b0d220baf7821874dc93f85fae 100644 (file)
@@ -52,7 +52,7 @@
 macro_rules! panictry {
     ($e:expr) => ({
         use std::result::Result::{Ok, Err};
-        use diagnostic::FatalError;
+        use errors::FatalError;
         match $e {
             Ok(e) => e,
             Err(FatalError) => panic!(FatalError)
@@ -78,6 +78,8 @@ pub mod diagnostics {
     pub mod metadata;
 }
 
+pub mod errors;
+
 pub mod syntax {
     pub use ext;
     pub use parse;
@@ -90,7 +92,6 @@ pub mod syntax {
 pub mod attr;
 pub mod codemap;
 pub mod config;
-pub mod diagnostic;
 pub mod entry;
 pub mod feature_gate;
 pub mod fold;
index 83369689a94de077efbce2a8ce81ff6e32c4751e..33a3d5785981ae50f55b9708fecef54b0e9331f2 100644 (file)
@@ -8,100 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::default::Default;
-use std::fmt;
-use std::iter::{IntoIterator, FromIterator};
-use std::ops::Deref;
-use std::slice;
-use std::vec;
-use serialize::{Encodable, Decodable, Encoder, Decoder};
-
-/// A non-growable owned slice. This is a separate type to allow the
-/// representation to change.
-#[derive(Hash, PartialEq, Eq, PartialOrd, Ord)]
-pub struct OwnedSlice<T> {
-    data: Box<[T]>
-}
-
-impl<T:fmt::Debug> fmt::Debug for OwnedSlice<T> {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        self.data.fmt(fmt)
-    }
-}
-
-impl<T> OwnedSlice<T> {
-    pub fn empty() -> OwnedSlice<T> {
-        OwnedSlice  { data: Box::new([]) }
-    }
-
-    #[inline(never)]
-    pub fn from_vec(v: Vec<T>) -> OwnedSlice<T> {
-        OwnedSlice { data: v.into_boxed_slice() }
-    }
-
-    #[inline(never)]
-    pub fn into_vec(self) -> Vec<T> {
-        self.data.into_vec()
-    }
-
-    pub fn as_slice<'a>(&'a self) -> &'a [T] {
-        &*self.data
-    }
-
-    pub fn move_iter(self) -> vec::IntoIter<T> {
-        self.into_vec().into_iter()
-    }
-
-    pub fn map<U, F: FnMut(&T) -> U>(&self, f: F) -> OwnedSlice<U> {
-        self.iter().map(f).collect()
-    }
-}
-
-impl<T> Deref for OwnedSlice<T> {
-    type Target = [T];
-
-    fn deref(&self) -> &[T] {
-        self.as_slice()
-    }
-}
-
-impl<T> Default for OwnedSlice<T> {
-    fn default() -> OwnedSlice<T> {
-        OwnedSlice::empty()
-    }
-}
-
-impl<T: Clone> Clone for OwnedSlice<T> {
-    fn clone(&self) -> OwnedSlice<T> {
-        OwnedSlice::from_vec(self.to_vec())
-    }
-}
-
-impl<T> FromIterator<T> for OwnedSlice<T> {
-    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> OwnedSlice<T> {
-        OwnedSlice::from_vec(iter.into_iter().collect())
-    }
-}
-
-impl<'a, T> IntoIterator for &'a OwnedSlice<T> {
-    type Item = &'a T;
-    type IntoIter = slice::Iter<'a, T>;
-    fn into_iter(self) -> Self::IntoIter {
-        self.data.into_iter()
-    }
-}
-
-impl<T: Encodable> Encodable for OwnedSlice<T> {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        Encodable::encode(&**self, s)
-    }
-}
-
-impl<T: Decodable> Decodable for OwnedSlice<T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<OwnedSlice<T>, D::Error> {
-        Ok(OwnedSlice::from_vec(match Decodable::decode(d) {
-            Ok(t) => t,
-            Err(e) => return Err(e)
-        }))
-    }
-}
+/// A non-growable owned slice.
+#[unstable(feature = "rustc_private", issue = "0")]
+#[rustc_deprecated(since = "1.7.0", reason = "use `ptr::P<[T]>` instead")]
+pub type OwnedSlice<T> = ::ptr::P<[T]>;
index e5e2c3a986db374b76b03711b51daf16f9eabbee..d2156d7cb68d25ae45b0420eb608b359ebe71ba7 100644 (file)
@@ -12,7 +12,7 @@
 
 use ast;
 use codemap::{BytePos, CharPos, CodeMap, Pos};
-use diagnostic;
+use errors;
 use parse::lexer::is_block_doc_comment;
 use parse::lexer::{StringReader, TokenAndSpan};
 use parse::lexer::{is_whitespace, Reader};
@@ -334,7 +334,7 @@ pub struct Literal {
 
 // it appears this function is called only from pprust... that's
 // probably not a good thing.
-pub fn gather_comments_and_literals(span_diagnostic: &diagnostic::SpanHandler,
+pub fn gather_comments_and_literals(span_diagnostic: &errors::Handler,
                                     path: String,
                                     srdr: &mut Read)
                                  -> (Vec<Comment>, Vec<Literal>) {
index cb2181a0831773c2426a437b5ba6df00878dedb3..4619410ada7274c44cefe8f08032684bff346d78 100644 (file)
@@ -11,8 +11,7 @@
 use ast;
 use codemap::{BytePos, CharPos, CodeMap, Pos, Span};
 use codemap;
-use diagnostic::FatalError;
-use diagnostic::SpanHandler;
+use errors::{FatalError, Handler};
 use ext::tt::transcribe::tt_next_token;
 use parse::token::str_to_ident;
 use parse::token;
@@ -58,7 +57,7 @@ pub struct TokenAndSpan {
 }
 
 pub struct StringReader<'a> {
-    pub span_diagnostic: &'a SpanHandler,
+    pub span_diagnostic: &'a Handler,
     /// The absolute offset within the codemap of the next character to read
     pub pos: BytePos,
     /// The absolute offset within the codemap of the last character read(curr)
@@ -128,10 +127,10 @@ fn peek(&self) -> TokenAndSpan {
 
 impl<'a> StringReader<'a> {
     /// For comments.rs, which hackily pokes into pos and curr
-    pub fn new_raw<'b>(span_diagnostic: &'b SpanHandler,
+    pub fn new_raw<'b>(span_diagnostic: &'b Handler,
                        filemap: Rc<codemap::FileMap>) -> StringReader<'b> {
         if filemap.src.is_none() {
-            span_diagnostic.handler.bug(&format!("Cannot lex filemap without source: {}",
+            span_diagnostic.bug(&format!("Cannot lex filemap without source: {}",
                                                  filemap.name)[..]);
         }
 
@@ -153,7 +152,7 @@ pub fn new_raw<'b>(span_diagnostic: &'b SpanHandler,
         sr
     }
 
-    pub fn new<'b>(span_diagnostic: &'b SpanHandler,
+    pub fn new<'b>(span_diagnostic: &'b Handler,
                    filemap: Rc<codemap::FileMap>) -> StringReader<'b> {
         let mut sr = StringReader::new_raw(span_diagnostic, filemap);
         sr.advance_token();
@@ -1423,28 +1422,30 @@ mod tests {
     use super::*;
 
     use codemap::{BytePos, CodeMap, Span, NO_EXPANSION};
-    use diagnostic;
+    use errors;
     use parse::token;
     use parse::token::{str_to_ident};
     use std::io;
+    use std::rc::Rc;
 
-    fn mk_sh() -> diagnostic::SpanHandler {
+    fn mk_sh(cm: Rc<CodeMap>) -> errors::Handler {
         // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
-        let emitter = diagnostic::EmitterWriter::new(Box::new(io::sink()), None);
-        let handler = diagnostic::Handler::with_emitter(true, Box::new(emitter));
-        diagnostic::SpanHandler::new(handler, CodeMap::new())
+        let emitter = errors::emitter::EmitterWriter::new(Box::new(io::sink()), None, cm);
+        errors::Handler::with_emitter(true, false, Box::new(emitter))
     }
 
     // open a string reader for the given string
-    fn setup<'a>(span_handler: &'a diagnostic::SpanHandler,
+    fn setup<'a>(cm: &CodeMap,
+                 span_handler: &'a errors::Handler,
                  teststr: String) -> StringReader<'a> {
-        let fm = span_handler.cm.new_filemap("zebra.rs".to_string(), teststr);
+        let fm = cm.new_filemap("zebra.rs".to_string(), teststr);
         StringReader::new(span_handler, fm)
     }
 
     #[test] fn t1 () {
-        let span_handler = mk_sh();
-        let mut string_reader = setup(&span_handler,
+        let cm = Rc::new(CodeMap::new());
+        let sh = mk_sh(cm.clone());
+        let mut string_reader = setup(&cm, &sh,
             "/* my source file */ \
              fn main() { println!(\"zebra\"); }\n".to_string());
         let id = str_to_ident("fn");
@@ -1482,21 +1483,27 @@ fn mk_ident(id: &str, style: token::IdentStyle) -> token::Token {
     }
 
     #[test] fn doublecolonparsing () {
-        check_tokenization(setup(&mk_sh(), "a b".to_string()),
+        let cm = Rc::new(CodeMap::new());
+        let sh = mk_sh(cm.clone());
+        check_tokenization(setup(&cm, &sh, "a b".to_string()),
                            vec![mk_ident("a", token::Plain),
                                 token::Whitespace,
                                 mk_ident("b", token::Plain)]);
     }
 
     #[test] fn dcparsing_2 () {
-        check_tokenization(setup(&mk_sh(), "a::b".to_string()),
+        let cm = Rc::new(CodeMap::new());
+        let sh = mk_sh(cm.clone());
+        check_tokenization(setup(&cm, &sh, "a::b".to_string()),
                            vec![mk_ident("a",token::ModName),
                                 token::ModSep,
                                 mk_ident("b", token::Plain)]);
     }
 
     #[test] fn dcparsing_3 () {
-        check_tokenization(setup(&mk_sh(), "a ::b".to_string()),
+        let cm = Rc::new(CodeMap::new());
+        let sh = mk_sh(cm.clone());
+        check_tokenization(setup(&cm, &sh, "a ::b".to_string()),
                            vec![mk_ident("a", token::Plain),
                                 token::Whitespace,
                                 token::ModSep,
@@ -1504,7 +1511,9 @@ fn mk_ident(id: &str, style: token::IdentStyle) -> token::Token {
     }
 
     #[test] fn dcparsing_4 () {
-        check_tokenization(setup(&mk_sh(), "a:: b".to_string()),
+        let cm = Rc::new(CodeMap::new());
+        let sh = mk_sh(cm.clone());
+        check_tokenization(setup(&cm, &sh, "a:: b".to_string()),
                            vec![mk_ident("a",token::ModName),
                                 token::ModSep,
                                 token::Whitespace,
@@ -1512,40 +1521,52 @@ fn mk_ident(id: &str, style: token::IdentStyle) -> token::Token {
     }
 
     #[test] fn character_a() {
-        assert_eq!(setup(&mk_sh(), "'a'".to_string()).next_token().tok,
+        let cm = Rc::new(CodeMap::new());
+        let sh = mk_sh(cm.clone());
+        assert_eq!(setup(&cm, &sh, "'a'".to_string()).next_token().tok,
                    token::Literal(token::Char(token::intern("a")), None));
     }
 
     #[test] fn character_space() {
-        assert_eq!(setup(&mk_sh(), "' '".to_string()).next_token().tok,
+        let cm = Rc::new(CodeMap::new());
+        let sh = mk_sh(cm.clone());
+        assert_eq!(setup(&cm, &sh, "' '".to_string()).next_token().tok,
                    token::Literal(token::Char(token::intern(" ")), None));
     }
 
     #[test] fn character_escaped() {
-        assert_eq!(setup(&mk_sh(), "'\\n'".to_string()).next_token().tok,
+        let cm = Rc::new(CodeMap::new());
+        let sh = mk_sh(cm.clone());
+        assert_eq!(setup(&cm, &sh, "'\\n'".to_string()).next_token().tok,
                    token::Literal(token::Char(token::intern("\\n")), None));
     }
 
     #[test] fn lifetime_name() {
-        assert_eq!(setup(&mk_sh(), "'abc".to_string()).next_token().tok,
+        let cm = Rc::new(CodeMap::new());
+        let sh = mk_sh(cm.clone());
+        assert_eq!(setup(&cm, &sh, "'abc".to_string()).next_token().tok,
                    token::Lifetime(token::str_to_ident("'abc")));
     }
 
     #[test] fn raw_string() {
-        assert_eq!(setup(&mk_sh(),
+        let cm = Rc::new(CodeMap::new());
+        let sh = mk_sh(cm.clone());
+        assert_eq!(setup(&cm, &sh,
                          "r###\"\"#a\\b\x00c\"\"###".to_string()).next_token()
                                                                  .tok,
                    token::Literal(token::StrRaw(token::intern("\"#a\\b\x00c\""), 3), None));
     }
 
     #[test] fn literal_suffixes() {
+        let cm = Rc::new(CodeMap::new());
+        let sh = mk_sh(cm.clone());
         macro_rules! test {
             ($input: expr, $tok_type: ident, $tok_contents: expr) => {{
-                assert_eq!(setup(&mk_sh(), format!("{}suffix", $input)).next_token().tok,
+                assert_eq!(setup(&cm, &sh, format!("{}suffix", $input)).next_token().tok,
                            token::Literal(token::$tok_type(token::intern($tok_contents)),
                                           Some(token::intern("suffix"))));
                 // with a whitespace separator:
-                assert_eq!(setup(&mk_sh(), format!("{} suffix", $input)).next_token().tok,
+                assert_eq!(setup(&cm, &sh, format!("{} suffix", $input)).next_token().tok,
                            token::Literal(token::$tok_type(token::intern($tok_contents)),
                                           None));
             }}
@@ -1561,13 +1582,13 @@ macro_rules! test {
         test!("1.0", Float, "1.0");
         test!("1.0e10", Float, "1.0e10");
 
-        assert_eq!(setup(&mk_sh(), "2us".to_string()).next_token().tok,
+        assert_eq!(setup(&cm, &sh, "2us".to_string()).next_token().tok,
                    token::Literal(token::Integer(token::intern("2")),
                                   Some(token::intern("us"))));
-        assert_eq!(setup(&mk_sh(), "r###\"raw\"###suffix".to_string()).next_token().tok,
+        assert_eq!(setup(&cm, &sh, "r###\"raw\"###suffix".to_string()).next_token().tok,
                    token::Literal(token::StrRaw(token::intern("raw"), 3),
                                   Some(token::intern("suffix"))));
-        assert_eq!(setup(&mk_sh(), "br###\"raw\"###suffix".to_string()).next_token().tok,
+        assert_eq!(setup(&cm, &sh, "br###\"raw\"###suffix".to_string()).next_token().tok,
                    token::Literal(token::ByteStrRaw(token::intern("raw"), 3),
                                   Some(token::intern("suffix"))));
     }
@@ -1579,8 +1600,9 @@ macro_rules! test {
     }
 
     #[test] fn nested_block_comments() {
-        let sh = mk_sh();
-        let mut lexer = setup(&sh, "/* /* */ */'a'".to_string());
+        let cm = Rc::new(CodeMap::new());
+        let sh = mk_sh(cm.clone());
+        let mut lexer = setup(&cm, &sh, "/* /* */ */'a'".to_string());
         match lexer.next_token().tok {
             token::Comment => { },
             _ => panic!("expected a comment!")
@@ -1589,8 +1611,9 @@ macro_rules! test {
     }
 
     #[test] fn crlf_comments() {
-        let sh = mk_sh();
-        let mut lexer = setup(&sh, "// test\r\n/// test\r\n".to_string());
+        let cm = Rc::new(CodeMap::new());
+        let sh = mk_sh(cm.clone());
+        let mut lexer = setup(&cm, &sh, "// test\r\n/// test\r\n".to_string());
         let comment = lexer.next_token();
         assert_eq!(comment.tok, token::Comment);
         assert_eq!(comment.sp, ::codemap::mk_sp(BytePos(0), BytePos(7)));
index e9c8173a4d9802e4bc6b0f5d7a36f0e6a06aa8e9..cff106f838af234c8b72591e313986b141853f78 100644 (file)
@@ -12,7 +12,7 @@
 
 use ast;
 use codemap::{self, Span, CodeMap, FileMap};
-use diagnostic::{SpanHandler, Handler, Auto, FatalError};
+use errors::{Handler, ColorConfig, FatalError};
 use parse::parser::Parser;
 use parse::token::InternedString;
 use ptr::P;
 
 /// Info about a parsing session.
 pub struct ParseSess {
-    pub span_diagnostic: SpanHandler, // better be the same as the one in the reader!
+    pub span_diagnostic: Handler, // better be the same as the one in the reader!
     /// Used to determine and report recursive mod inclusions
     included_mod_stack: RefCell<Vec<PathBuf>>,
+    code_map: Rc<CodeMap>,
 }
 
 impl ParseSess {
     pub fn new() -> ParseSess {
-        let handler = SpanHandler::new(Handler::new(Auto, None, true), CodeMap::new());
-        ParseSess::with_span_handler(handler)
+        let cm = Rc::new(CodeMap::new());
+        let handler = Handler::new(ColorConfig::Auto, None, true, false, cm.clone());
+        ParseSess::with_span_handler(handler, cm)
     }
 
-    pub fn with_span_handler(sh: SpanHandler) -> ParseSess {
+    pub fn with_span_handler(handler: Handler, code_map: Rc<CodeMap>) -> ParseSess {
         ParseSess {
-            span_diagnostic: sh,
-            included_mod_stack: RefCell::new(vec![])
+            span_diagnostic: handler,
+            included_mod_stack: RefCell::new(vec![]),
+            code_map: code_map
         }
     }
 
     pub fn codemap(&self) -> &CodeMap {
-        &self.span_diagnostic.cm
+        &self.code_map
     }
 }
 
@@ -235,7 +238,7 @@ fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
             let msg = format!("couldn't read {:?}: {}", path.display(), e);
             match spanopt {
                 Some(sp) => panic!(sess.span_diagnostic.span_fatal(sp, &msg)),
-                None => panic!(sess.span_diagnostic.handler().fatal(&msg))
+                None => panic!(sess.span_diagnostic.fatal(&msg))
             }
         }
     }
@@ -438,7 +441,7 @@ fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
 }
 
 fn filtered_float_lit(data: token::InternedString, suffix: Option<&str>,
-                      sd: &SpanHandler, sp: Span) -> ast::Lit_ {
+                      sd: &Handler, sp: Span) -> ast::Lit_ {
     debug!("filtered_float_lit: {}, {:?}", data, suffix);
     match suffix.as_ref().map(|s| &**s) {
         Some("f32") => ast::LitFloat(data, ast::TyF32),
@@ -459,7 +462,7 @@ fn filtered_float_lit(data: token::InternedString, suffix: Option<&str>,
     }
 }
 pub fn float_lit(s: &str, suffix: Option<InternedString>,
-                 sd: &SpanHandler, sp: Span) -> ast::Lit_ {
+                 sd: &Handler, sp: Span) -> ast::Lit_ {
     debug!("float_lit: {:?}, {:?}", s, suffix);
     // FIXME #2252: bounds checking float literals is deferred until trans
     let s = s.chars().filter(|&c| c != '_').collect::<String>();
@@ -561,7 +564,7 @@ fn eat<'a, I: Iterator<Item=(usize, u8)>>(it: &mut iter::Peekable<I>) {
 
 pub fn integer_lit(s: &str,
                    suffix: Option<InternedString>,
-                   sd: &SpanHandler,
+                   sd: &Handler,
                    sp: Span)
                    -> ast::Lit_ {
     // s can only be ascii, byte indexing is fine
@@ -668,7 +671,6 @@ mod tests {
     use super::*;
     use std::rc::Rc;
     use codemap::{Span, BytePos, Pos, Spanned, NO_EXPANSION};
-    use owned_slice::OwnedSlice;
     use ast::{self, TokenTree};
     use abi;
     use attr::{first_attr_value_str_by_name, AttrMetaMethods};
@@ -944,7 +946,7 @@ fn parser_done(p: Parser){
                                     abi::Rust,
                                     ast::Generics{ // no idea on either of these:
                                         lifetimes: Vec::new(),
-                                        ty_params: OwnedSlice::empty(),
+                                        ty_params: P::empty(),
                                         where_clause: ast::WhereClause {
                                             id: ast::DUMMY_NODE_ID,
                                             predicates: Vec::new(),
index bc355f70fb31e92637a3e3a712ecd4581570cde5..5dba1e189ab156dcb8ca3c0a65c17a01ad883de7 100644 (file)
@@ -66,10 +66,9 @@ fn report(&mut self,
         }
 
         if !self.obsolete_set.contains(&kind) &&
-            (error || self.sess.span_diagnostic.handler().can_emit_warnings) {
+            (error || self.sess.span_diagnostic.can_emit_warnings) {
             self.sess
                 .span_diagnostic
-                .handler()
                 .note(&format!("{}", desc));
             self.obsolete_set.insert(kind);
         }
index 712f4e3801275258e570fa7183db60e3f9b9b7b2..ebfcf8c5180cf6454ff133d3902c6d4aca29e058 100644 (file)
@@ -50,7 +50,7 @@
 use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef};
 use ast::{Ty, Ty_, TypeBinding, TyMac};
 use ast::{TyFixedLengthVec, TyBareFn, TyTypeof, TyInfer};
-use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPtr};
+use ast::{TyParam, TyParamBounds, TyParen, TyPath, TyPtr};
 use ast::{TyRptr, TyTup, TyU32, TyVec};
 use ast::TypeTraitItem;
 use ast::{UnnamedField, UnsafeBlock};
@@ -60,7 +60,7 @@
 use ast;
 use ast_util::{self, ident_to_path};
 use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap};
-use diagnostic;
+use errors::{self, FatalError};
 use ext::tt::macro_parser;
 use parse;
 use parse::classify;
@@ -73,9 +73,7 @@
 use util::parser::{AssocOp, Fixity};
 use print::pprust;
 use ptr::P;
-use owned_slice::OwnedSlice;
 use parse::PResult;
-use diagnostic::FatalError;
 
 use std::collections::HashSet;
 use std::io::prelude::*;
@@ -752,7 +750,7 @@ pub fn expect_gt(&mut self) -> PResult<()> {
     pub fn parse_seq_to_before_gt_or_return<T, F>(&mut self,
                                                   sep: Option<token::Token>,
                                                   mut f: F)
-                                                  -> PResult<(OwnedSlice<T>, bool)> where
+                                                  -> PResult<(P<[T]>, bool)> where
         F: FnMut(&mut Parser) -> PResult<Option<T>>,
     {
         let mut v = Vec::new();
@@ -773,7 +771,7 @@ pub fn parse_seq_to_before_gt_or_return<T, F>(&mut self,
             if i % 2 == 0 {
                 match try!(f(self)) {
                     Some(result) => v.push(result),
-                    None => return Ok((OwnedSlice::from_vec(v), true))
+                    None => return Ok((P::from_vec(v), true))
                 }
             } else {
                 if let Some(t) = sep.as_ref() {
@@ -782,7 +780,7 @@ pub fn parse_seq_to_before_gt_or_return<T, F>(&mut self,
 
             }
         }
-        return Ok((OwnedSlice::from_vec(v), false));
+        return Ok((P::from_vec(v), false));
     }
 
     /// Parse a sequence bracketed by '<' and '>', stopping
@@ -790,7 +788,7 @@ pub fn parse_seq_to_before_gt_or_return<T, F>(&mut self,
     pub fn parse_seq_to_before_gt<T, F>(&mut self,
                                         sep: Option<token::Token>,
                                         mut f: F)
-                                        -> PResult<OwnedSlice<T>> where
+                                        -> PResult<P<[T]>> where
         F: FnMut(&mut Parser) -> PResult<T>,
     {
         let (result, returned) = try!(self.parse_seq_to_before_gt_or_return(sep,
@@ -802,7 +800,7 @@ pub fn parse_seq_to_before_gt<T, F>(&mut self,
     pub fn parse_seq_to_gt<T, F>(&mut self,
                                  sep: Option<token::Token>,
                                  f: F)
-                                 -> PResult<OwnedSlice<T>> where
+                                 -> PResult<P<[T]>> where
         F: FnMut(&mut Parser) -> PResult<T>,
     {
         let v = try!(self.parse_seq_to_before_gt(sep, f));
@@ -813,7 +811,7 @@ pub fn parse_seq_to_gt<T, F>(&mut self,
     pub fn parse_seq_to_gt_or_return<T, F>(&mut self,
                                            sep: Option<token::Token>,
                                            f: F)
-                                           -> PResult<(OwnedSlice<T>, bool)> where
+                                           -> PResult<(P<[T]>, bool)> where
         F: FnMut(&mut Parser) -> PResult<Option<T>>,
     {
         let (v, returned) = try!(self.parse_seq_to_before_gt_or_return(sep, f));
@@ -983,16 +981,16 @@ pub fn look_ahead<R, F>(&mut self, distance: usize, f: F) -> R where
         }
         f(&self.buffer[((self.buffer_start + dist - 1) & 3) as usize].tok)
     }
-    pub fn fatal(&self, m: &str) -> diagnostic::FatalError {
+    pub fn fatal(&self, m: &str) -> errors::FatalError {
         self.sess.span_diagnostic.span_fatal(self.span, m)
     }
-    pub fn span_fatal(&self, sp: Span, m: &str) -> diagnostic::FatalError {
+    pub fn span_fatal(&self, sp: Span, m: &str) -> errors::FatalError {
         self.sess.span_diagnostic.span_fatal(sp, m)
     }
-    pub fn span_fatal_help(&self, sp: Span, m: &str, help: &str) -> diagnostic::FatalError {
+    pub fn span_fatal_help(&self, sp: Span, m: &str, help: &str) -> errors::FatalError {
         self.span_err(sp, m);
         self.fileline_help(sp, help);
-        diagnostic::FatalError
+        errors::FatalError
     }
     pub fn span_note(&self, sp: Span, m: &str) {
         self.sess.span_diagnostic.span_note(sp, m)
@@ -1022,7 +1020,7 @@ pub fn span_bug(&self, sp: Span, m: &str) -> ! {
         self.sess.span_diagnostic.span_bug(sp, m)
     }
     pub fn abort_if_errors(&self) {
-        self.sess.span_diagnostic.handler().abort_if_errors();
+        self.sess.span_diagnostic.abort_if_errors();
     }
 
     pub fn id_to_interned_str(&mut self, id: Ident) -> InternedString {
@@ -1077,7 +1075,7 @@ pub fn parse_for_in_type(&mut self) -> PResult<Ty_> {
             let other_bounds = if try!(self.eat(&token::BinOp(token::Plus)) ){
                 try!(self.parse_ty_param_bounds(BoundParsingMode::Bare))
             } else {
-                OwnedSlice::empty()
+                P::empty()
             };
             let all_bounds =
                 Some(TraitTyParamBound(poly_trait_ref, TraitBoundModifier::None)).into_iter()
@@ -1710,8 +1708,8 @@ pub fn parse_path_segments_without_colons(&mut self) -> PResult<Vec<ast::PathSeg
 
                 ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
                     lifetimes: lifetimes,
-                    types: OwnedSlice::from_vec(types),
-                    bindings: OwnedSlice::from_vec(bindings),
+                    types: P::from_vec(types),
+                    bindings: P::from_vec(bindings),
                 })
             } else if try!(self.eat(&token::OpenDelim(token::Paren)) ){
                 let lo = self.last_span.lo;
@@ -1774,8 +1772,8 @@ pub fn parse_path_segments_with_colons(&mut self) -> PResult<Vec<ast::PathSegmen
                     identifier: identifier,
                     parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
                         lifetimes: lifetimes,
-                        types: OwnedSlice::from_vec(types),
-                        bindings: OwnedSlice::from_vec(bindings),
+                        types: P::from_vec(types),
+                        bindings: P::from_vec(bindings),
                     }),
                 });
 
@@ -3883,10 +3881,10 @@ fn handle_expression_like_statement(
     // otherwise returns empty list.
     fn parse_colon_then_ty_param_bounds(&mut self,
                                         mode: BoundParsingMode)
-                                        -> PResult<OwnedSlice<TyParamBound>>
+                                        -> PResult<TyParamBounds>
     {
         if !try!(self.eat(&token::Colon) ){
-            Ok(OwnedSlice::empty())
+            Ok(P::empty())
         } else {
             self.parse_ty_param_bounds(mode)
         }
@@ -3898,7 +3896,7 @@ fn parse_colon_then_ty_param_bounds(&mut self,
     // and     bound     = 'region | trait_ref
     fn parse_ty_param_bounds(&mut self,
                              mode: BoundParsingMode)
-                             -> PResult<OwnedSlice<TyParamBound>>
+                             -> PResult<TyParamBounds>
     {
         let mut result = vec!();
         loop {
@@ -3940,7 +3938,7 @@ fn parse_ty_param_bounds(&mut self,
             }
         }
 
-        return Ok(OwnedSlice::from_vec(result));
+        return Ok(P::from_vec(result));
     }
 
     /// Matches typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?
index 4e2289cb7f401324d83fb01e62204690a080f2ff..1f296dc5d59bd6e83153106d57e0423d1cd6e9a5 100644 (file)
 use attr::ThinAttributesExt;
 use util::parser::AssocOp;
 use attr;
-use owned_slice::OwnedSlice;
 use attr::{AttrMetaMethods, AttributeMethods};
 use codemap::{self, CodeMap, BytePos};
-use diagnostic;
+use errors;
 use parse::token::{self, BinOpToken, Token, InternedString};
 use parse::lexer::comments;
 use parse;
@@ -99,7 +98,7 @@ pub fn rust_printer_annotated<'a>(writer: Box<Write+'a>,
 /// it can scan the input text for comments and literals to
 /// copy forward.
 pub fn print_crate<'a>(cm: &'a CodeMap,
-                       span_diagnostic: &diagnostic::SpanHandler,
+                       span_diagnostic: &errors::Handler,
                        krate: &ast::Crate,
                        filename: String,
                        input: &mut Read,
@@ -139,7 +138,7 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
 
 impl<'a> State<'a> {
     pub fn new_from_input(cm: &'a CodeMap,
-                          span_diagnostic: &diagnostic::SpanHandler,
+                          span_diagnostic: &errors::Handler,
                           filename: String,
                           input: &mut Read,
                           out: Box<Write+'a>,
@@ -1001,7 +1000,7 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> {
             ast::TyBareFn(ref f) => {
                 let generics = ast::Generics {
                     lifetimes: f.lifetimes.clone(),
-                    ty_params: OwnedSlice::empty(),
+                    ty_params: P::empty(),
                     where_clause: ast::WhereClause {
                         id: ast::DUMMY_NODE_ID,
                         predicates: Vec::new(),
@@ -3024,7 +3023,7 @@ pub fn print_ty_fn(&mut self,
         }
         let generics = ast::Generics {
             lifetimes: Vec::new(),
-            ty_params: OwnedSlice::empty(),
+            ty_params: P::empty(),
             where_clause: ast::WhereClause {
                 id: ast::DUMMY_NODE_ID,
                 predicates: Vec::new(),
index 83e321f110c5875dfb39694307fbde3afd1f94f1..1be0b08086d9ce830028441184dc1ee43a285ce7 100644 (file)
 //!   Moreover, a switch to, e.g. `P<'a, T>` would be easy and mostly automated.
 
 use std::fmt::{self, Display, Debug};
-use std::hash::{Hash, Hasher};
+use std::iter::FromIterator;
 use std::ops::Deref;
-use std::ptr;
+use std::{ptr, slice, vec};
 
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
 /// An owned smart pointer.
-pub struct P<T> {
+#[derive(Hash, PartialEq, Eq, PartialOrd, Ord)]
+pub struct P<T: ?Sized> {
     ptr: Box<T>
 }
 
@@ -92,14 +93,6 @@ fn clone(&self) -> P<T> {
     }
 }
 
-impl<T: PartialEq> PartialEq for P<T> {
-    fn eq(&self, other: &P<T>) -> bool {
-        **self == **other
-    }
-}
-
-impl<T: Eq> Eq for P<T> {}
-
 impl<T: Debug> Debug for P<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         Debug::fmt(&**self, f)
@@ -111,19 +104,12 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
 impl<T> fmt::Pointer for P<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::Pointer::fmt(&self.ptr, f)
     }
 }
 
-impl<T: Hash> Hash for P<T> {
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        (**self).hash(state);
-    }
-}
-
 impl<T: 'static + Decodable> Decodable for P<T> {
     fn decode<D: Decoder>(d: &mut D) -> Result<P<T>, D::Error> {
         Decodable::decode(d).map(P)
@@ -135,3 +121,87 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
         (**self).encode(s)
     }
 }
+
+
+impl<T:fmt::Debug> fmt::Debug for P<[T]> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        self.ptr.fmt(fmt)
+    }
+}
+
+impl<T> P<[T]> {
+    pub fn empty() -> P<[T]> {
+        P { ptr: Default::default() }
+    }
+
+    #[inline(never)]
+    pub fn from_vec(v: Vec<T>) -> P<[T]> {
+        P { ptr: v.into_boxed_slice() }
+    }
+
+    #[inline(never)]
+    pub fn into_vec(self) -> Vec<T> {
+        self.ptr.into_vec()
+    }
+
+    pub fn as_slice<'a>(&'a self) -> &'a [T] {
+        &*self.ptr
+    }
+
+    pub fn move_iter(self) -> vec::IntoIter<T> {
+        self.into_vec().into_iter()
+    }
+
+    pub fn map<U, F: FnMut(&T) -> U>(&self, f: F) -> P<[U]> {
+        self.iter().map(f).collect()
+    }
+}
+
+impl<T> Deref for P<[T]> {
+    type Target = [T];
+
+    fn deref(&self) -> &[T] {
+        self.as_slice()
+    }
+}
+
+impl<T> Default for P<[T]> {
+    fn default() -> P<[T]> {
+        P::empty()
+    }
+}
+
+impl<T: Clone> Clone for P<[T]> {
+    fn clone(&self) -> P<[T]> {
+        P::from_vec(self.to_vec())
+    }
+}
+
+impl<T> FromIterator<T> for P<[T]> {
+    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> P<[T]> {
+        P::from_vec(iter.into_iter().collect())
+    }
+}
+
+impl<'a, T> IntoIterator for &'a P<[T]> {
+    type Item = &'a T;
+    type IntoIter = slice::Iter<'a, T>;
+    fn into_iter(self) -> Self::IntoIter {
+        self.ptr.into_iter()
+    }
+}
+
+impl<T: Encodable> Encodable for P<[T]> {
+    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+        Encodable::encode(&**self, s)
+    }
+}
+
+impl<T: Decodable> Decodable for P<[T]> {
+    fn decode<D: Decoder>(d: &mut D) -> Result<P<[T]>, D::Error> {
+        Ok(P::from_vec(match Decodable::decode(d) {
+            Ok(t) => t,
+            Err(e) => return Err(e)
+        }))
+    }
+}
index 6492cd4b095a775260897f12b606f360c8f0abad..014c7b2a68f4f36935f96b38b726a1e6086d82c0 100644 (file)
@@ -16,7 +16,7 @@
 use std::str::FromStr;
 
 use ast;
-use diagnostic;
+use errors;
 use visit;
 use visit::Visitor;
 
@@ -40,7 +40,7 @@ fn from_str(s: &str) -> Result<Mode, ()> {
 }
 
 struct ShowSpanVisitor<'a> {
-    span_diagnostic: &'a diagnostic::SpanHandler,
+    span_diagnostic: &'a errors::Handler,
     mode: Mode,
 }
 
@@ -71,7 +71,7 @@ fn visit_mac(&mut self, mac: &ast::Mac) {
     }
 }
 
-pub fn run(span_diagnostic: &diagnostic::SpanHandler,
+pub fn run(span_diagnostic: &errors::Handler,
            mode: &str,
            krate: &ast::Crate) {
     let mode = match mode.parse().ok() {
index 63fbe284a09fd6f4f0e9e0d057d0c2ef2859c8bc..9a6d1f8fdab4dd3170c57c63370b8a9733fceb91 100644 (file)
@@ -23,7 +23,7 @@
 use attr;
 use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute};
 use codemap;
-use diagnostic;
+use errors;
 use config;
 use entry::{self, EntryPointType};
 use ext::base::ExtCtxt;
@@ -32,7 +32,6 @@
 use fold::Folder;
 use util::move_map::MoveMap;
 use fold;
-use owned_slice::OwnedSlice;
 use parse::token::{intern, InternedString};
 use parse::{token, ParseSess};
 use print::pprust;
@@ -55,7 +54,7 @@ struct Test {
 
 struct TestCtxt<'a> {
     sess: &'a ParseSess,
-    span_diagnostic: &'a diagnostic::SpanHandler,
+    span_diagnostic: &'a errors::Handler,
     path: Vec<ast::Ident>,
     ext_cx: ExtCtxt<'a>,
     testfns: Vec<Test>,
@@ -72,7 +71,7 @@ struct TestCtxt<'a> {
 pub fn modify_for_testing(sess: &ParseSess,
                           cfg: &ast::CrateConfig,
                           krate: ast::Crate,
-                          span_diagnostic: &diagnostic::SpanHandler) -> ast::Crate {
+                          span_diagnostic: &errors::Handler) -> ast::Crate {
     // We generate the test harness when building in the 'test'
     // configuration, either with the '--test' or '--cfg test'
     // command line options.
@@ -275,7 +274,7 @@ fn generate_test_harness(sess: &ParseSess,
                          reexport_test_harness_main: Option<InternedString>,
                          krate: ast::Crate,
                          cfg: &ast::CrateConfig,
-                         sd: &diagnostic::SpanHandler) -> ast::Crate {
+                         sd: &errors::Handler) -> ast::Crate {
     // Remove the entry points
     let mut cleaner = EntryPointCleaner { depth: 0 };
     let krate = cleaner.fold_crate(krate);
@@ -315,7 +314,7 @@ fn generate_test_harness(sess: &ParseSess,
     return res;
 }
 
-fn strip_test_functions(diagnostic: &diagnostic::SpanHandler, krate: ast::Crate)
+fn strip_test_functions(diagnostic: &errors::Handler, krate: ast::Crate)
                         -> ast::Crate {
     // When not compiling with --test we should not compile the
     // #[test] functions
@@ -688,7 +687,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
         Some(id) => vec![id],
         None => {
             let diag = cx.span_diagnostic;
-            diag.handler.bug("expected to find top-level re-export name, but found None");
+            diag.bug("expected to find top-level re-export name, but found None");
         }
     };
     visible_path.extend(path);
index 95c24c66630f048298814882ddebfccdc77693b6..e1078b719bf0679f07c4a64be63f6b817e556a42 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use owned_slice::OwnedSlice;
-
 use std::ptr;
 
 pub trait MoveMap<T>: Sized {
@@ -69,11 +67,11 @@ fn move_flat_map<F, I>(mut self, mut f: F) -> Self
     }
 }
 
-impl<T> MoveMap<T> for OwnedSlice<T> {
+impl<T> MoveMap<T> for ::ptr::P<[T]> {
     fn move_flat_map<F, I>(self, f: F) -> Self
         where F: FnMut(T) -> I,
               I: IntoIterator<Item=T>
     {
-        OwnedSlice::from_vec(self.into_vec().move_flat_map(f))
+        ::ptr::P::from_vec(self.into_vec().move_flat_map(f))
     }
 }
index 5977144dae708b402011020338cb0b91b9691209..8f316649421a6511a6e2e1e1ae26ece5aadb8398 100644 (file)
 use syntax::ext::build::AstBuilder;
 use syntax::codemap::{self, DUMMY_SP};
 use syntax::codemap::Span;
-use syntax::diagnostic::SpanHandler;
+use syntax::errors::Handler;
 use syntax::util::move_map::MoveMap;
-use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token::{intern, InternedString};
 use syntax::parse::token::special_idents;
 use syntax::ptr::P;
@@ -516,7 +515,7 @@ fn create_derived_impl(&self,
 
             cx.typaram(self.span,
                        ty_param.ident,
-                       OwnedSlice::from_vec(bounds),
+                       P::from_vec(bounds),
                        None)
         }));
 
@@ -528,7 +527,7 @@ fn create_derived_impl(&self,
                         span: self.span,
                         bound_lifetimes: wb.bound_lifetimes.clone(),
                         bounded_ty: wb.bounded_ty.clone(),
-                        bounds: OwnedSlice::from_vec(wb.bounds.iter().cloned().collect())
+                        bounds: P::from_vec(wb.bounds.iter().cloned().collect())
                     })
                 }
                 ast::WherePredicate::RegionPredicate(ref rb) => {
@@ -579,7 +578,7 @@ fn create_derived_impl(&self,
                         span: self.span,
                         bound_lifetimes: vec![],
                         bounded_ty: ty,
-                        bounds: OwnedSlice::from_vec(bounds),
+                        bounds: P::from_vec(bounds),
                     };
 
                     let predicate = ast::WherePredicate::BoundPredicate(predicate);
@@ -590,7 +589,7 @@ fn create_derived_impl(&self,
 
         let trait_generics = Generics {
             lifetimes: lifetimes,
-            ty_params: OwnedSlice::from_vec(ty_params),
+            ty_params: P::from_vec(ty_params),
             where_clause: where_clause
         };
 
@@ -742,7 +741,7 @@ fn expand_enum_def(&self,
     }
 }
 
-fn find_repr_type_name(diagnostic: &SpanHandler,
+fn find_repr_type_name(diagnostic: &Handler,
                        type_attrs: &[ast::Attribute]) -> &'static str {
     let mut repr_type_name = "i32";
     for a in type_attrs {
index 0c4a81361aef2568e3705b795d4bba9ae55149fa..10564b5f6985b7c407b2c05a9b4b9b758ed288f5 100644 (file)
@@ -19,7 +19,6 @@
 use syntax::ext::base::ExtCtxt;
 use syntax::ext::build::AstBuilder;
 use syntax::codemap::{Span,respan};
-use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token::special_idents;
 use syntax::ptr::P;
 
@@ -209,7 +208,7 @@ fn mk_generics(lifetimes: Vec<ast::LifetimeDef>, ty_params: Vec<ast::TyParam>)
                -> Generics {
     Generics {
         lifetimes: lifetimes,
-        ty_params: OwnedSlice::from_vec(ty_params),
+        ty_params: P::from_vec(ty_params),
         where_clause: ast::WhereClause {
             id: ast::DUMMY_NODE_ID,
             predicates: Vec::new(),
index f4dd621c97ecdcb02a856531b6fe75f9bb476f76..01dc9662588bfab02877dee362ad170fa407ec99 100644 (file)
@@ -39,7 +39,7 @@
 macro_rules! panictry {
     ($e:expr) => ({
         use std::result::Result::{Ok, Err};
-        use syntax::diagnostic::FatalError;
+        use syntax::errors::FatalError;
         match $e {
             Ok(e) => e,
             Err(FatalError) => panic!(FatalError)
diff --git a/src/test/run-make/emit/Makefile b/src/test/run-make/emit/Makefile
new file mode 100644 (file)
index 0000000..be34028
--- /dev/null
@@ -0,0 +1,15 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) -Copt-level=0 --emit=llvm-bc,llvm-ir,asm,obj,link test-24876.rs
+       $(RUSTC) -Copt-level=1 --emit=llvm-bc,llvm-ir,asm,obj,link test-24876.rs
+       $(RUSTC) -Copt-level=2 --emit=llvm-bc,llvm-ir,asm,obj,link test-24876.rs
+       $(RUSTC) -Copt-level=3 --emit=llvm-bc,llvm-ir,asm,obj,link test-24876.rs
+       $(RUSTC) -Copt-level=0 --emit=llvm-bc,llvm-ir,asm,obj,link test-26235.rs
+       $(call RUN,test-26235) || exit 1
+       $(RUSTC) -Copt-level=1 --emit=llvm-bc,llvm-ir,asm,obj,link test-26235.rs
+       $(call RUN,test-26235) || exit 1
+       $(RUSTC) -Copt-level=2 --emit=llvm-bc,llvm-ir,asm,obj,link test-26235.rs
+       $(call RUN,test-26235) || exit 1
+       $(RUSTC) -Copt-level=3 --emit=llvm-bc,llvm-ir,asm,obj,link test-26235.rs
+       $(call RUN,test-26235) || exit 1
diff --git a/src/test/run-make/emit/test-24876.rs b/src/test/run-make/emit/test-24876.rs
new file mode 100644 (file)
index 0000000..ab69dec
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+// Checks for issue #24876
+
+fn main() {
+    let mut v = 0;
+    for i in 0..0 {
+        v += i;
+    }
+    println!("{}", v)
+}
diff --git a/src/test/run-make/emit/test-26235.rs b/src/test/run-make/emit/test-26235.rs
new file mode 100644 (file)
index 0000000..97b58a3
--- /dev/null
@@ -0,0 +1,56 @@
+// 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.
+
+// Checks for issue #26235
+
+fn main() {
+    use std::thread;
+
+    type Key = u32;
+    const NUM_THREADS: usize = 2;
+
+    #[derive(Clone,Copy)]
+    struct Stats<S> {
+        upsert: S,
+        delete: S,
+        insert: S,
+        update: S
+    };
+
+    impl<S> Stats<S> where S: Copy {
+        fn dot<B, F, T>(self, s: Stats<T>, f: F) -> Stats<B> where F: Fn(S, T) -> B {
+            let Stats { upsert: u1, delete: d1, insert: i1, update: p1 } = self;
+            let Stats { upsert: u2, delete: d2, insert: i2, update: p2 } = s;
+            Stats { upsert: f(u1, u2), delete: f(d1, d2), insert: f(i1, i2), update: f(p1, p2) }
+        }
+
+        fn new(init: S) -> Self {
+            Stats { upsert: init, delete: init, insert: init, update: init }
+        }
+    }
+
+    fn make_threads() -> Vec<thread::JoinHandle<()>> {
+        let mut t = Vec::with_capacity(NUM_THREADS);
+        for _ in 0..NUM_THREADS {
+            t.push(thread::spawn(move || {}));
+        }
+        t
+    }
+
+    let stats = [Stats::new(0); NUM_THREADS];
+    make_threads();
+
+    {
+        let Stats { ref upsert, ref delete, ref insert, ref update } = stats.iter().fold(
+            Stats::new(0), |res, &s| res.dot(s, |x: Key, y: Key| x.wrapping_add(y)));
+        println!("upserts: {}, deletes: {}, inserts: {}, updates: {}",
+                 upsert, delete, insert, update);
+    }
+}
index e40abe050233331444fb50cb880ba377578d261c..7c1a45d020b22d61c84a280965eeffd773b31e3e 100644 (file)
@@ -44,7 +44,7 @@ fn with_error_checking_parse<T, F>(s: String, f: F) -> PResult<T> where
     let mut p = string_to_parser(&ps, s);
     let x = f(&mut p);
 
-    if ps.span_diagnostic.handler().has_errors() || p.token != token::Eof {
+    if ps.span_diagnostic.has_errors() || p.token != token::Eof {
         return Err(p.fatal("parse error"));
     }
 
index 8850f6e6d2a6e5863db91511efd4438bba2925d5..e3eeeb863568800949e95c08d3bbe57d9910d2ef 100644 (file)
@@ -23,7 +23,7 @@
 use rustc::session::Session;
 use rustc::session::config::{self, Input};
 use rustc_driver::{driver, CompilerCalls, Compilation};
-use syntax::{diagnostics, diagnostic};
+use syntax::{diagnostics, errors};
 
 use std::path::PathBuf;
 
@@ -35,7 +35,7 @@ impl<'a> CompilerCalls<'a> for TestCalls {
     fn early_callback(&mut self,
                       _: &getopts::Matches,
                       _: &diagnostics::registry::Registry,
-                      _: diagnostic::ColorConfig)
+                      _: errors::emitter::ColorConfig)
                       -> Compilation {
         self.count *= 2;
         Compilation::Continue