]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/session/config.rs
rollup merge of #21457: alexcrichton/issue-21436
[rust.git] / src / librustc / session / config.rs
index d3f8c8284e0dc38eb1eadbeac3d8a04afdeb770f..a2bba313cca87331810027506a364395f18998ba 100644 (file)
@@ -99,7 +99,7 @@ pub struct Options {
     pub parse_only: bool,
     pub no_trans: bool,
     pub no_analysis: bool,
-    pub debugging_opts: u64,
+    pub debugging_opts: DebuggingOptions,
     /// Whether to write dependency files. It's (enabled, optional filename).
     pub write_dependency_info: (bool, Option<Path>),
     pub prints: Vec<PrintRequest>,
@@ -111,7 +111,24 @@ pub struct Options {
     /// An optional name to use as the crate for std during std injection,
     /// written `extern crate std = "name"`. Default to "std". Used by
     /// out-of-tree drivers.
-    pub alt_std_name: Option<String>
+    pub alt_std_name: Option<String>,
+    /// Indicates how the compiler should treat unstable features
+    pub unstable_features: UnstableFeatures
+}
+
+#[derive(Clone, Copy)]
+pub enum UnstableFeatures {
+    /// Hard errors for unstable features are active, as on
+    /// beta/stable channels.
+    Disallow,
+    /// Use the default lint levels
+    Default,
+    /// Errors are bypassed for bootstrapping. This is required any time
+    /// during the build that feature-related lints are set to warn or above
+    /// because the build turns on warnings-as-errors and uses lots of unstable
+    /// features. As a result, this this is always required for building Rust
+    /// itself.
+    Cheat
 }
 
 #[derive(Clone, PartialEq, Eq)]
@@ -207,7 +224,7 @@ pub fn basic_options() -> Options {
         parse_only: false,
         no_trans: false,
         no_analysis: false,
-        debugging_opts: 0,
+        debugging_opts: basic_debugging_options(),
         write_dependency_info: (false, None),
         prints: Vec::new(),
         cg: basic_codegen_options(),
@@ -217,6 +234,7 @@ pub fn basic_options() -> Options {
         crate_name: None,
         alt_std_name: None,
         libs: Vec::new(),
+        unstable_features: UnstableFeatures::Disallow
     }
 }
 
@@ -231,7 +249,7 @@ pub enum EntryFnType {
     EntryNone,
 }
 
-#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash)]
+#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Show)]
 pub enum CrateType {
     CrateTypeExecutable,
     CrateTypeDylib,
@@ -239,103 +257,6 @@ pub enum CrateType {
     CrateTypeStaticlib,
 }
 
-macro_rules! debugging_opts {
-    ([ $opt:ident ] $cnt:expr ) => (
-        pub const $opt: u64 = 1 << $cnt;
-    );
-    ([ $opt:ident, $($rest:ident),* ] $cnt:expr ) => (
-        pub const $opt: u64 = 1 << $cnt;
-        debugging_opts! { [ $($rest),* ] $cnt + 1 }
-    )
-}
-
-debugging_opts! {
-    [
-        VERBOSE,
-        TIME_PASSES,
-        COUNT_LLVM_INSNS,
-        TIME_LLVM_PASSES,
-        TRANS_STATS,
-        ASM_COMMENTS,
-        NO_VERIFY,
-        BORROWCK_STATS,
-        NO_LANDING_PADS,
-        DEBUG_LLVM,
-        COUNT_TYPE_SIZES,
-        META_STATS,
-        GC,
-        PRINT_LINK_ARGS,
-        PRINT_LLVM_PASSES,
-        AST_JSON,
-        AST_JSON_NOEXPAND,
-        LS,
-        SAVE_ANALYSIS,
-        PRINT_MOVE_FRAGMENTS,
-        FLOWGRAPH_PRINT_LOANS,
-        FLOWGRAPH_PRINT_MOVES,
-        FLOWGRAPH_PRINT_ASSIGNS,
-        FLOWGRAPH_PRINT_ALL,
-        PRINT_REGION_GRAPH,
-        PARSE_ONLY,
-        NO_TRANS,
-        NO_ANALYSIS,
-        UNSTABLE_OPTIONS,
-        PRINT_ENUM_SIZES
-    ]
-    0
-}
-
-pub fn debugging_opts_map() -> Vec<(&'static str, &'static str, u64)> {
-    vec![("verbose", "in general, enable more debug printouts", VERBOSE),
-     ("time-passes", "measure time of each rustc pass", TIME_PASSES),
-     ("count-llvm-insns", "count where LLVM \
-                           instrs originate", COUNT_LLVM_INSNS),
-     ("time-llvm-passes", "measure time of each LLVM pass",
-      TIME_LLVM_PASSES),
-     ("trans-stats", "gather trans statistics", TRANS_STATS),
-     ("asm-comments", "generate comments into the assembly (may change behavior)",
-      ASM_COMMENTS),
-     ("no-verify", "skip LLVM verification", NO_VERIFY),
-     ("borrowck-stats", "gather borrowck statistics",  BORROWCK_STATS),
-     ("no-landing-pads", "omit landing pads for unwinding",
-      NO_LANDING_PADS),
-     ("debug-llvm", "enable debug output from LLVM", DEBUG_LLVM),
-     ("count-type-sizes", "count the sizes of aggregate types",
-      COUNT_TYPE_SIZES),
-     ("meta-stats", "gather metadata statistics", META_STATS),
-     ("print-link-args", "Print the arguments passed to the linker",
-      PRINT_LINK_ARGS),
-     ("gc", "Garbage collect shared data (experimental)", GC),
-     ("print-llvm-passes",
-      "Prints the llvm optimization passes being run",
-      PRINT_LLVM_PASSES),
-     ("ast-json", "Print the AST as JSON and halt", AST_JSON),
-     ("ast-json-noexpand", "Print the pre-expansion AST as JSON and halt", AST_JSON_NOEXPAND),
-     ("ls", "List the symbols defined by a library crate", LS),
-     ("save-analysis", "Write syntax and type analysis information \
-                        in addition to normal output", SAVE_ANALYSIS),
-     ("print-move-fragments", "Print out move-fragment data for every fn",
-      PRINT_MOVE_FRAGMENTS),
-     ("flowgraph-print-loans", "Include loan analysis data in \
-                       --pretty flowgraph output", FLOWGRAPH_PRINT_LOANS),
-     ("flowgraph-print-moves", "Include move analysis data in \
-                       --pretty flowgraph output", FLOWGRAPH_PRINT_MOVES),
-     ("flowgraph-print-assigns", "Include assignment analysis data in \
-                       --pretty flowgraph output", FLOWGRAPH_PRINT_ASSIGNS),
-     ("flowgraph-print-all", "Include all dataflow analysis data in \
-                       --pretty flowgraph output", FLOWGRAPH_PRINT_ALL),
-     ("print-region-graph", "Prints region inference graph. \
-                             Use with RUST_REGION_GRAPH=help for more info",
-      PRINT_REGION_GRAPH),
-     ("parse-only", "Parse only; do not compile, assemble, or link", PARSE_ONLY),
-     ("no-trans", "Run all passes except translation; no output", NO_TRANS),
-     ("no-analysis", "Parse and expand the source, but run no analysis and",
-      NO_TRANS),
-     ("unstable-options", "Adds unstable command line options to rustc interface",
-      UNSTABLE_OPTIONS),
-     ("print-enum-sizes", "Print the size of enums and their variants", PRINT_ENUM_SIZES),
-    ]
-}
 
 #[derive(Clone)]
 pub enum Passes {
@@ -352,7 +273,7 @@ pub fn is_empty(&self) -> bool {
     }
 }
 
-/// Declare a macro that will define all CodegenOptions fields and parsers all
+/// Declare a macro that will define all CodegenOptions/DebuggingOptions fields and parsers all
 /// at once. The goal of this macro is to define an interface that can be
 /// programmatically used by the option parser in order to initialize the struct
 /// without hardcoding field names all over the place.
@@ -362,23 +283,70 @@ pub fn is_empty(&self) -> bool {
 /// cgsetters module which is a bunch of generated code to parse an option into
 /// its respective field in the struct. There are a few hand-written parsers for
 /// parsing specific types of values in this module.
-macro_rules! cgoptions {
-    ($($opt:ident : $t:ty = ($init:expr, $parse:ident, $desc:expr)),* ,) =>
+macro_rules! options {
+    ($struct_name:ident, $setter_name:ident, $defaultfn:ident,
+     $buildfn:ident, $prefix:expr, $outputname:expr,
+     $stat:ident, $mod_desc:ident, $mod_set:ident,
+     $($opt:ident : $t:ty = ($init:expr, $parse:ident, $desc:expr)),* ,) =>
 (
     #[derive(Clone)]
-    pub struct CodegenOptions { $(pub $opt: $t),* }
+    #[allow(missing_copy_implementations)]
+    pub struct $struct_name { $(pub $opt: $t),* }
 
-    pub fn basic_codegen_options() -> CodegenOptions {
-        CodegenOptions { $($opt: $init),* }
+    pub fn $defaultfn() -> $struct_name {
+        $struct_name { $($opt: $init),* }
     }
 
-    pub type CodegenSetter = fn(&mut CodegenOptions, v: Option<&str>) -> bool;
-    pub const CG_OPTIONS: &'static [(&'static str, CodegenSetter,
+    pub fn $buildfn(matches: &getopts::Matches) -> $struct_name
+    {
+        let mut op = $defaultfn();
+        for option in matches.opt_strs($prefix).into_iter() {
+            let mut iter = option.splitn(1, '=');
+            let key = iter.next().unwrap();
+            let value = iter.next();
+            let option_to_lookup = key.replace("-", "_");
+            let mut found = false;
+            for &(candidate, setter, opt_type_desc, _) in $stat.iter() {
+                if option_to_lookup != candidate { continue }
+                if !setter(&mut op, value) {
+                    match (value, opt_type_desc) {
+                        (Some(..), None) => {
+                            early_error(&format!("{} option `{}` takes no \
+                                                 value", $outputname, key)[])
+                        }
+                        (None, Some(type_desc)) => {
+                            early_error(&format!("{0} option `{1}` requires \
+                                                 {2} ({3} {1}=<value>)",
+                                                $outputname, key,
+                                                type_desc, $prefix)[])
+                        }
+                        (Some(value), Some(type_desc)) => {
+                            early_error(&format!("incorrect value `{}` for {} \
+                                                 option `{}` - {} was expected",
+                                                 value, $outputname,
+                                                 key, type_desc)[])
+                        }
+                        (None, None) => unreachable!()
+                    }
+                }
+                found = true;
+                break;
+            }
+            if !found {
+                early_error(&format!("unknown codegen option: `{}`",
+                                    key)[]);
+            }
+        }
+        return op;
+    }
+
+    pub type $setter_name = fn(&mut $struct_name, v: Option<&str>) -> bool;
+    pub const $stat: &'static [(&'static str, $setter_name,
                                      Option<&'static str>, &'static str)] =
-        &[ $( (stringify!($opt), cgsetters::$opt, cg_type_descs::$parse, $desc) ),* ];
+        &[ $( (stringify!($opt), $mod_set::$opt, $mod_desc::$parse, $desc) ),* ];
 
-    #[allow(non_upper_case_globals)]
-    mod cg_type_descs {
+    #[allow(non_upper_case_globals, dead_code)]
+    mod $mod_desc {
         pub const parse_bool: Option<&'static str> = None;
         pub const parse_opt_bool: Option<&'static str> = None;
         pub const parse_string: Option<&'static str> = Some("a string");
@@ -392,11 +360,12 @@ mod cg_type_descs {
             Some("a number");
     }
 
-    mod cgsetters {
-        use super::{CodegenOptions, Passes, SomePasses, AllPasses};
+    #[allow(dead_code)]
+    mod $mod_set {
+        use super::{$struct_name, Passes, SomePasses, AllPasses};
 
         $(
-            pub fn $opt(cg: &mut CodegenOptions, v: Option<&str>) -> bool {
+            pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool {
                 $parse(&mut cg.$opt, v)
             }
         )*
@@ -488,7 +457,9 @@ fn parse_passes(slot: &mut Passes, v: Option<&str>) -> bool {
     }
 ) }
 
-cgoptions! {
+options! {CodegenOptions, CodegenSetter, basic_codegen_options,
+         build_codegen_options, "C", "codegen",
+         CG_OPTIONS, cg_type_desc, cgsetters,
     ar: Option<String> = (None, parse_opt_string,
         "tool to assemble archives with"),
     linker: Option<String> = (None, parse_opt_string,
@@ -544,45 +515,73 @@ fn parse_passes(slot: &mut Passes, v: Option<&str>) -> bool {
         "Optimize with possible levels 0-3"),
 }
 
-pub fn build_codegen_options(matches: &getopts::Matches) -> CodegenOptions
-{
-    let mut cg = basic_codegen_options();
-    for option in matches.opt_strs("C").into_iter() {
-        let mut iter = option.splitn(1, '=');
-        let key = iter.next().unwrap();
-        let value = iter.next();
-        let option_to_lookup = key.replace("-", "_");
-        let mut found = false;
-        for &(candidate, setter, opt_type_desc, _) in CG_OPTIONS.iter() {
-            if option_to_lookup != candidate { continue }
-            if !setter(&mut cg, value) {
-                match (value, opt_type_desc) {
-                    (Some(..), None) => {
-                        early_error(format!("codegen option `{}` takes no \
-                                             value", key).index(&FullRange))
-                    }
-                    (None, Some(type_desc)) => {
-                        early_error(format!("codegen option `{0}` requires \
-                                             {1} (-C {0}=<value>)",
-                                            key, type_desc).index(&FullRange))
-                    }
-                    (Some(value), Some(type_desc)) => {
-                        early_error(format!("incorrect value `{}` for codegen \
-                                             option `{}` - {} was expected",
-                                             value, key, type_desc).index(&FullRange))
-                    }
-                    (None, None) => unreachable!()
-                }
-            }
-            found = true;
-            break;
-        }
-        if !found {
-            early_error(format!("unknown codegen option: `{}`",
-                                key).index(&FullRange));
-        }
-    }
-    return cg;
+
+options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
+         build_debugging_options, "Z", "debugging",
+         DB_OPTIONS, db_type_desc, dbsetters,
+    verbose: bool = (false, parse_bool,
+        "in general, enable more debug printouts"),
+    time_passes: bool = (false, parse_bool,
+        "measure time of each rustc pass"),
+    count_llvm_insns: bool = (false, parse_bool,
+        "count where LLVM instrs originate"),
+    time_llvm_passes: bool = (false, parse_bool,
+        "measure time of each LLVM pass"),
+    trans_stats: bool = (false, parse_bool,
+        "gather trans statistics"),
+    asm_comments: bool = (false, parse_bool,
+        "generate comments into the assembly (may change behavior)"),
+    no_verify: bool = (false, parse_bool,
+        "skip LLVM verification"),
+    borrowck_stats: bool = (false, parse_bool,
+        "gather borrowck statistics"),
+    no_landing_pads: bool = (false, parse_bool,
+        "omit landing pads for unwinding"),
+    debug_llvm: bool = (false, parse_bool,
+        "enable debug output from LLVM"),
+    count_type_sizes: bool = (false, parse_bool,
+        "count the sizes of aggregate types"),
+    meta_stats: bool = (false, parse_bool,
+        "gather metadata statistics"),
+    print_link_args: bool = (false, parse_bool,
+        "Print the arguments passed to the linker"),
+    gc: bool = (false, parse_bool,
+        "Garbage collect shared data (experimental)"),
+    print_llvm_passes: bool = (false, parse_bool,
+        "Prints the llvm optimization passes being run"),
+    ast_json: bool = (false, parse_bool,
+        "Print the AST as JSON and halt"),
+    ast_json_noexpand: bool = (false, parse_bool,
+        "Print the pre-expansion AST as JSON and halt"),
+    ls: bool = (false, parse_bool,
+        "List the symbols defined by a library crate"),
+    save_analysis: bool = (false, parse_bool,
+        "Write syntax and type analysis information in addition to normal output"),
+    print_move_fragments: bool = (false, parse_bool,
+        "Print out move-fragment data for every fn"),
+    flowgraph_print_loans: bool = (false, parse_bool,
+        "Include loan analysis data in --pretty flowgraph output"),
+    flowgraph_print_moves: bool = (false, parse_bool,
+        "Include move analysis data in --pretty flowgraph output"),
+    flowgraph_print_assigns: bool = (false, parse_bool,
+        "Include assignment analysis data in --pretty flowgraph output"),
+    flowgraph_print_all: bool = (false, parse_bool,
+        "Include all dataflow analysis data in --pretty flowgraph output"),
+    print_region_graph: bool = (false, parse_bool,
+         "Prints region inference graph. \
+          Use with RUST_REGION_GRAPH=help for more info"),
+    parse_only: bool = (false, parse_bool,
+          "Parse only; do not compile, assemble, or link"),
+    no_trans: bool = (false, parse_bool,
+          "Run all passes except translation; no output"),
+    no_analysis: bool = (false, parse_bool,
+          "Parse and expand the source, but run no analysis"),
+    extra_plugins: Vec<String> = (Vec::new(), parse_list,
+        "load extra plugins"),
+    unstable_options: bool = (false, parse_bool,
+          "Adds unstable command line options to rustc interface"),
+    print_enum_sizes: bool = (false, parse_bool,
+          "Print the size of enums and their variants"),
 }
 
 pub fn default_lib_output() -> CrateType {
@@ -592,10 +591,10 @@ pub fn default_lib_output() -> CrateType {
 pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
     use syntax::parse::token::intern_and_get_ident as intern;
 
-    let end = sess.target.target.target_endian.index(&FullRange);
-    let arch = sess.target.target.arch.index(&FullRange);
-    let wordsz = sess.target.target.target_word_size.index(&FullRange);
-    let os = sess.target.target.target_os.index(&FullRange);
+    let end = &sess.target.target.target_endian[];
+    let arch = &sess.target.target.arch[];
+    let wordsz = &sess.target.target.target_pointer_width[];
+    let os = &sess.target.target.target_os[];
 
     let fam = match sess.target.target.options.is_like_windows {
         true  => InternedString::new("windows"),
@@ -609,7 +608,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
          mk(InternedString::new("target_family"), fam),
          mk(InternedString::new("target_arch"), intern(arch)),
          mk(InternedString::new("target_endian"), intern(end)),
-         mk(InternedString::new("target_word_size"),
+         mk(InternedString::new("target_pointer_width"),
             intern(wordsz))
     );
 }
@@ -631,23 +630,23 @@ pub fn build_configuration(sess: &Session) -> ast::CrateConfig {
         append_configuration(&mut user_cfg, InternedString::new("test"))
     }
     let mut v = user_cfg.into_iter().collect::<Vec<_>>();
-    v.push_all(default_cfg.index(&FullRange));
+    v.push_all(&default_cfg[]);
     v
 }
 
 pub fn build_target_config(opts: &Options, sp: &SpanHandler) -> Config {
-    let target = match Target::search(opts.target_triple.index(&FullRange)) {
+    let target = match Target::search(&opts.target_triple[]) {
         Ok(t) => t,
         Err(e) => {
             sp.handler().fatal((format!("Error loading target specification: {}", e)).as_slice());
     }
     };
 
-    let (int_type, uint_type) = match target.target_word_size.index(&FullRange) {
+    let (int_type, uint_type) = match &target.target_pointer_width[] {
         "32" => (ast::TyI32, ast::TyU32),
         "64" => (ast::TyI64, ast::TyU64),
-        w    => sp.handler().fatal((format!("target specification was invalid: unrecognized \
-                                            target-word-size {}", w)).index(&FullRange))
+        w    => sp.handler().fatal(&format!("target specification was invalid: unrecognized \
+                                            target-word-size {}", w)[])
     };
 
     Config {
@@ -787,7 +786,6 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
         opt::multi("", "extern", "Specify where an external rust library is \
                                 located",
                  "NAME=PATH"),
-        opt::opt("", "opt-level", "Optimize with possible levels 0-3", "LEVEL"),
         opt::opt("", "sysroot", "Override the system root", "PATH"),
         opt::multi("Z", "", "Set internal debugging options", "FLAG"),
         opt::opt("", "color", "Configure coloring of output:
@@ -795,22 +793,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
             always = always colorize output;
             never  = never colorize output", "auto|always|never"),
 
-        // DEPRECATED
-        opt::flag("", "print-crate-name", "Output the crate name and exit"),
-        opt::flag("", "print-file-name", "Output the file(s) that would be \
-                                        written if compilation \
-                                        continued and exit"),
-        opt::opt("",  "debuginfo",  "Emit DWARF debug info to the objects created:
-             0 = no debug info,
-             1 = line-tables only (for stacktraces and breakpoints),
-             2 = full debug info with variable and type information \
-                    (same as -g)", "LEVEL"),
-        opt::flag("", "no-trans", "Run all passes except translation; no output"),
-        opt::flag("", "no-analysis", "Parse and expand the source, but run no \
-                                    analysis and produce no output"),
-        opt::flag("", "parse-only", "Parse only; do not compile, assemble, \
-                                   or link"),
-        opt::flagopt("", "pretty",
+        opt::flagopt_u("", "pretty",
                    "Pretty-print the input instead of compiling;
                    valid types are: `normal` (un-annotated source),
                    `expanded` (crates expanded),
@@ -824,9 +807,6 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
                       `everybody_loops` (all function bodies replaced with `loop {}`).",
                      "TYPE"),
         opt::opt_u("", "show-span", "Show spans for compiler debugging", "expr|pat|ty"),
-        opt::flagopt("", "dep-info",
-                 "Output dependency info to <filename> after compiling, \
-                  in a format suitable for use by Makefiles", "FILENAME"),
     ]);
     opts
 }
@@ -845,7 +825,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     let unparsed_crate_types = matches.opt_strs("crate-type");
     let crate_types = parse_crate_types_from_list(unparsed_crate_types)
-        .unwrap_or_else(|e| early_error(e.index(&FullRange)));
+        .unwrap_or_else(|e| early_error(&e[]));
 
     let mut lint_opts = vec!();
     let mut describe_lints = false;
@@ -860,52 +840,18 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         }
     }
 
-    let mut debugging_opts = 0;
-    let debug_flags = matches.opt_strs("Z");
-    let debug_map = debugging_opts_map();
-    for debug_flag in debug_flags.iter() {
-        let mut this_bit = 0;
-        for &(name, _, bit) in debug_map.iter() {
-            if name == *debug_flag {
-                this_bit = bit;
-                break;
-            }
-        }
-        if this_bit == 0 {
-            early_error(format!("unknown debug flag: {}",
-                                *debug_flag).index(&FullRange))
-        }
-        debugging_opts |= this_bit;
-    }
+    let debugging_opts = build_debugging_options(matches);
 
-    let parse_only = if matches.opt_present("parse-only") {
-        // FIXME(acrichto) remove this eventually
-        early_warn("--parse-only is deprecated in favor of -Z parse-only");
-        true
-    } else {
-        debugging_opts & PARSE_ONLY != 0
-    };
-    let no_trans = if matches.opt_present("no-trans") {
-        // FIXME(acrichto) remove this eventually
-        early_warn("--no-trans is deprecated in favor of -Z no-trans");
-        true
-    } else {
-        debugging_opts & NO_TRANS != 0
-    };
-    let no_analysis = if matches.opt_present("no-analysis") {
-        // FIXME(acrichto) remove this eventually
-        early_warn("--no-analysis is deprecated in favor of -Z no-analysis");
-        true
-    } else {
-        debugging_opts & NO_ANALYSIS != 0
-    };
+    let parse_only = debugging_opts.parse_only;
+    let no_trans = debugging_opts.no_trans;
+    let no_analysis = debugging_opts.no_analysis;
 
-    if debugging_opts & DEBUG_LLVM != 0 {
+    if debugging_opts.debug_llvm {
         unsafe { llvm::LLVMSetDebug(1); }
     }
 
     let mut output_types = Vec::new();
-    if !parse_only && !no_trans {
+    if !debugging_opts.parse_only && !no_trans {
         let unparsed_output_types = matches.opt_strs("emit");
         for unparsed_output_type in unparsed_output_types.iter() {
             for part in unparsed_output_type.split(',') {
@@ -917,8 +863,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
                     "link" => OutputTypeExe,
                     "dep-info" => OutputTypeDepInfo,
                     _ => {
-                        early_error(format!("unknown emission type: `{}`",
-                                            part).index(&FullRange))
+                        early_error(&format!("unknown emission type: `{}`",
+                                            part)[])
                     }
                 };
                 output_types.push(output_type)
@@ -938,28 +884,10 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         host_triple().to_string());
     let opt_level = {
         if matches.opt_present("O") {
-            if matches.opt_present("opt-level") {
-                early_error("-O and --opt-level both provided");
-            }
             if cg.opt_level.is_some() {
                 early_error("-O and -C opt-level both provided");
             }
             Default
-        } else if matches.opt_present("opt-level") {
-            // FIXME(acrichto) remove this eventually
-            early_warn("--opt-level=N is deprecated in favor of -C opt-level=N");
-            match matches.opt_str("opt-level").as_ref().map(|s| s.as_slice()) {
-                None      |
-                Some("0") => No,
-                Some("1") => Less,
-                Some("2") => Default,
-                Some("3") => Aggressive,
-                Some(arg) => {
-                    early_error(format!("optimization level needs to be \
-                                         between 0-3 (instead was `{}`)",
-                                        arg).index(&FullRange));
-                }
-            }
         } else {
             match cg.opt_level {
                 None => No,
@@ -975,29 +903,12 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
             }
         }
     };
-    let gc = debugging_opts & GC != 0;
+    let gc = debugging_opts.gc;
     let debuginfo = if matches.opt_present("g") {
-        if matches.opt_present("debuginfo") {
-            early_error("-g and --debuginfo both provided");
-        }
         if cg.debuginfo.is_some() {
             early_error("-g and -C debuginfo both provided");
         }
         FullDebugInfo
-    } else if matches.opt_present("debuginfo") {
-        // FIXME(acrichto) remove this eventually
-        early_warn("--debuginfo=N is deprecated in favor of -C debuginfo=N");
-        match matches.opt_str("debuginfo").as_ref().map(|s| s.as_slice()) {
-            Some("0") => NoDebugInfo,
-            Some("1") => LimitedDebugInfo,
-            None      |
-            Some("2") => FullDebugInfo,
-            Some(arg) => {
-                early_error(format!("debug info level needs to be between \
-                                     0-2 (instead was `{}`)",
-                                    arg).index(&FullRange));
-            }
-        }
     } else {
         match cg.debuginfo {
             None | Some(0) => NoDebugInfo,
@@ -1013,7 +924,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     let mut search_paths = SearchPaths::new();
     for s in matches.opt_strs("L").iter() {
-        search_paths.add_path(s.index(&FullRange));
+        search_paths.add_path(&s[]);
     }
 
     let libs = matches.opt_strs("l").into_iter().map(|s| {
@@ -1043,9 +954,9 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
             (Some(name), "framework") => (name, cstore::NativeFramework),
             (Some(name), "static") => (name, cstore::NativeStatic),
             (_, s) => {
-                early_error(format!("unknown library kind `{}`, expected \
+                early_error(&format!("unknown library kind `{}`, expected \
                                      one of dylib, framework, or static",
-                                    s).index(&FullRange));
+                                    s)[]);
             }
         };
         (name.to_string(), kind)
@@ -1053,15 +964,9 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
     let test = matches.opt_present("test");
-    let write_dependency_info = if matches.opt_present("dep-info") {
-        // FIXME(acrichto) remove this eventually
-        early_warn("--dep-info has been deprecated in favor of --emit");
-        (true, matches.opt_str("dep-info").map(|p| Path::new(p)))
-    } else {
-        (output_types.contains(&OutputTypeDepInfo), None)
-    };
+    let write_dependency_info = (output_types.contains(&OutputTypeDepInfo), None);
 
-    let mut prints = matches.opt_strs("print").into_iter().map(|s| {
+    let prints = matches.opt_strs("print").into_iter().map(|s| {
         match s.as_slice() {
             "crate-name" => PrintRequest::CrateName,
             "file-names" => PrintRequest::FileNames,
@@ -1071,25 +976,13 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
             }
         }
     }).collect::<Vec<_>>();
-    if matches.opt_present("print-crate-name") {
-        // FIXME(acrichto) remove this eventually
-        early_warn("--print-crate-name has been deprecated in favor of \
-                    --print crate-name");
-        prints.push(PrintRequest::CrateName);
-    }
-    if matches.opt_present("print-file-name") {
-        // FIXME(acrichto) remove this eventually
-        early_warn("--print-file-name has been deprecated in favor of \
-                    --print file-names");
-        prints.push(PrintRequest::FileNames);
-    }
 
     if !cg.remark.is_empty() && debuginfo == NoDebugInfo {
         early_warn("-C remark will not show source locations without \
                     --debuginfo");
     }
 
-    let color = match matches.opt_str("color").as_ref().map(|s| s.index(&FullRange)) {
+    let color = match matches.opt_str("color").as_ref().map(|s| &s[]) {
         Some("auto")   => Auto,
         Some("always") => Always,
         Some("never")  => Never,
@@ -1097,9 +990,9 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         None => Auto,
 
         Some(arg) => {
-            early_error(format!("argument for --color must be auto, always \
+            early_error(&format!("argument for --color must be auto, always \
                                  or never (instead was `{}`)",
-                                arg).index(&FullRange))
+                                arg)[])
         }
     };
 
@@ -1115,7 +1008,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
             None => early_error("--extern value must be of the format `foo=bar`"),
         };
 
-        match externs.entry(&name.to_string()) {
+        match externs.entry(name.to_string()) {
             Vacant(entry) => { entry.insert(vec![location.to_string()]); },
             Occupied(mut entry) => { entry.get_mut().push(location.to_string()); },
         }
@@ -1149,6 +1042,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         crate_name: crate_name,
         alt_std_name: None,
         libs: libs,
+        unstable_features: UnstableFeatures::Disallow
     }
 }
 
@@ -1175,7 +1069,7 @@ pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateTy
     return Ok(crate_types);
 }
 
-impl fmt::Show for CrateType {
+impl fmt::Display for CrateType {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             CrateTypeExecutable => "bin".fmt(f),
@@ -1201,7 +1095,7 @@ mod test {
     #[test]
     fn test_switch_implies_cfg_test() {
         let matches =
-            &match getopts(&["--test".to_string()], optgroups().index(&FullRange)) {
+            &match getopts(&["--test".to_string()], &optgroups()[]) {
               Ok(m) => m,
               Err(f) => panic!("test_switch_implies_cfg_test: {}", f)
             };
@@ -1209,7 +1103,7 @@ fn test_switch_implies_cfg_test() {
         let sessopts = build_session_options(matches);
         let sess = build_session(sessopts, None, registry);
         let cfg = build_configuration(&sess);
-        assert!((attr::contains_name(cfg.index(&FullRange), "test")));
+        assert!((attr::contains_name(&cfg[], "test")));
     }
 
     // When the user supplies --test and --cfg test, don't implicitly add
@@ -1218,7 +1112,7 @@ fn test_switch_implies_cfg_test() {
     fn test_switch_implies_cfg_test_unless_cfg_test() {
         let matches =
             &match getopts(&["--test".to_string(), "--cfg=test".to_string()],
-                           optgroups().index(&FullRange)) {
+                           &optgroups()[]) {
               Ok(m) => m,
               Err(f) => {
                 panic!("test_switch_implies_cfg_test_unless_cfg_test: {}", f)
@@ -1238,7 +1132,7 @@ fn test_can_print_warnings() {
         {
             let matches = getopts(&[
                 "-Awarnings".to_string()
-            ], optgroups().index(&FullRange)).unwrap();
+            ], &optgroups()[]).unwrap();
             let registry = diagnostics::registry::Registry::new(&[]);
             let sessopts = build_session_options(&matches);
             let sess = build_session(sessopts, None, registry);
@@ -1249,7 +1143,7 @@ fn test_can_print_warnings() {
             let matches = getopts(&[
                 "-Awarnings".to_string(),
                 "-Dwarnings".to_string()
-            ], optgroups().index(&FullRange)).unwrap();
+            ], &optgroups()[]).unwrap();
             let registry = diagnostics::registry::Registry::new(&[]);
             let sessopts = build_session_options(&matches);
             let sess = build_session(sessopts, None, registry);
@@ -1259,7 +1153,7 @@ fn test_can_print_warnings() {
         {
             let matches = getopts(&[
                 "-Adead_code".to_string()
-            ], optgroups().index(&FullRange)).unwrap();
+            ], &optgroups()[]).unwrap();
             let registry = diagnostics::registry::Registry::new(&[]);
             let sessopts = build_session_options(&matches);
             let sess = build_session(sessopts, None, registry);