]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #35340 - michaelwoerister:incr-comp-cli-args, r=nikomatsakis
authorbors <bors@rust-lang.org>
Mon, 15 Aug 2016 15:35:18 +0000 (08:35 -0700)
committerGitHub <noreply@github.com>
Mon, 15 Aug 2016 15:35:18 +0000 (08:35 -0700)
Take commandline arguments into account for incr. comp.

Implements the conservative strategy described in https://github.com/rust-lang/rust/issues/33727.

From now one, every time a new commandline option is added, one has to specify if it influences the incremental compilation cache. I've tried to implement this as automatic as possible: One just has to added either the `[TRACKED]` or the `[UNTRACKED]` marker next to the field. The `Options`, `CodegenOptions`, and `DebuggingOptions` definitions in `session::config` show plenty of examples.

The PR removes some cruft from `session::config::Options`, mostly unnecessary copies of flags also present in `DebuggingOptions` or `CodeGenOptions` in the same struct.

One notable removal is the `cfg` field that contained the values passed via `--cfg` commandline arguments. I chose to remove it because (1) its content is only a subset of what later is stored in `hir::Crate::config` and it's pretty likely that reading the cfgs from `Options` would not be what you wanted, and (2) we could not incorporate it into the dep-tracking hash of the `Options` struct because of how the test framework works, leaving us with a piece of untracked but vital data.

It is now recommended (just as before) to access the crate config via the `krate()` method in the HIR map.

Because the `cfg` field is not present in the `Options` struct any more, some methods in the `CompilerCalls` trait now take the crate config as an explicit parameter -- which might constitute a breaking change for plugin authors.

1  2 
src/librustc_driver/driver.rs
src/librustc_metadata/loader.rs
src/librustc_trans/base.rs
src/libsyntax/feature_gate.rs
src/tools/compiletest/src/runtest.rs

index 70b1261730b07092aca68f7cd721d75bb7a7121f,568d98ac8d6009c19f72e646413ab38323386bc5..c6100004786bef8b97f9018cf30d7cddbd71cd49
@@@ -15,7 -15,8 +15,8 @@@ use rustc::hir::lowering::lower_crate
  use rustc_mir as mir;
  use rustc::mir::mir_map::MirMap;
  use rustc::session::{Session, CompileResult, compile_result_from_err_count};
- use rustc::session::config::{self, Input, OutputFilenames, OutputType};
+ use rustc::session::config::{self, Input, OutputFilenames, OutputType,
+                              OutputTypes};
  use rustc::session::search_paths::PathKind;
  use rustc::lint;
  use rustc::middle::{self, dependency_format, stability, reachable};
@@@ -42,7 -43,6 +43,6 @@@ use super::Compilation
  
  use serialize::json;
  
- use std::collections::HashMap;
  use std::env;
  use std::ffi::{OsString, OsStr};
  use std::fs;
@@@ -478,7 -478,7 +478,7 @@@ pub fn phase_1_parse_input<'a>(sess: &'
                                 cfg: ast::CrateConfig,
                                 input: &Input)
                                 -> PResult<'a, ast::Crate> {
-     let continue_after_error = sess.opts.continue_parse_after_error;
+     let continue_after_error = sess.opts.debugging_opts.continue_parse_after_error;
      sess.diagnostic().set_continue_after_error(continue_after_error);
  
      let krate = time(sess.time_passes(), "parsing", || {
@@@ -667,17 -667,22 +667,20 @@@ pub fn phase_2_configure_and_expand<'a
              trace_mac: sess.opts.debugging_opts.trace_macros,
              should_test: sess.opts.test,
          };
-         let mut loader = macro_import::MacroLoader::new(sess, &cstore, crate_name);
+         let mut loader = macro_import::MacroLoader::new(sess,
+                                                         &cstore,
+                                                         crate_name,
+                                                         krate.config.clone());
          let mut ecx = syntax::ext::base::ExtCtxt::new(&sess.parse_sess,
                                                        krate.config.clone(),
                                                        cfg,
                                                        &mut loader);
          syntax_ext::register_builtins(&mut ecx.syntax_env);
 -        let (ret, macro_names) = syntax::ext::expand::expand_crate(ecx,
 -                                                                   syntax_exts,
 -                                                                   krate);
 +        let ret = syntax::ext::expand::expand_crate(&mut ecx, syntax_exts, krate);
          if cfg!(windows) {
              env::set_var("PATH", &old_path);
          }
 -        *sess.available_macros.borrow_mut() = macro_names;
 +        *sess.available_macros.borrow_mut() = ecx.syntax_env.names;
          ret
      });
  
@@@ -1024,11 -1029,10 +1027,10 @@@ pub fn phase_5_run_llvm_passes(sess: &S
                                 trans: &trans::CrateTranslation,
                                 outputs: &OutputFilenames) -> CompileResult {
      if sess.opts.cg.no_integrated_as {
-         let mut map = HashMap::new();
-         map.insert(OutputType::Assembly, None);
+         let output_types = OutputTypes::new(&[(OutputType::Assembly, None)]);
          time(sess.time_passes(),
               "LLVM passes",
-              || write::run_passes(sess, trans, &map, outputs));
+              || write::run_passes(sess, trans, &output_types, outputs));
  
          write::run_assembler(sess, outputs);
  
index cf1dd71a0a12acbc8477f37438d67647dd135f13,543a9c88a586a847b8bac39337ed63848b0f870d..2345cd9a92aea2792c0cc77cedc90726370fb5c9
@@@ -400,7 -400,7 +400,7 @@@ impl<'a> Context<'a> 
          if self.hash.is_none() {
              self.should_match_name = false;
              if let Some(s) = self.sess.opts.externs.get(self.crate_name) {
-                 return self.find_commandline_library(s);
+                 return self.find_commandline_library(s.iter());
              }
              self.should_match_name = true;
          }
          (t.options.staticlib_prefix.clone(), t.options.staticlib_suffix.clone())
      }
  
-     fn find_commandline_library(&mut self, locs: &[String]) -> Option<Library> {
+     fn find_commandline_library<'b, LOCS> (&mut self, locs: LOCS) -> Option<Library>
+         where LOCS: Iterator<Item=&'b String>
+     {
          // First, filter out all libraries that look suspicious. We only accept
          // files which actually exist that have the correct naming scheme for
          // rlibs/dylibs.
          let mut rlibs = HashMap::new();
          let mut dylibs = HashMap::new();
          {
-             let locs = locs.iter().map(|l| PathBuf::from(l)).filter(|loc| {
+             let locs = locs.map(|l| PathBuf::from(l)).filter(|loc| {
                  if !loc.exists() {
                      sess.err(&format!("extern location for {} does not exist: {}",
                                       self.crate_name, loc.display()));
@@@ -867,29 -869,34 +869,29 @@@ fn get_metadata_section_imp(target: &Ta
  }
  
  pub fn meta_section_name(target: &Target) -> &'static str {
 +    // Historical note:
 +    //
 +    // When using link.exe it was seen that the section name `.note.rustc`
 +    // was getting shortened to `.note.ru`, and according to the PE and COFF
 +    // specification:
 +    //
 +    // > Executable images do not use a string table and do not support
 +    // > section names longer than 8 characters
 +    //
 +    // https://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx
 +    //
 +    // As a result, we choose a slightly shorter name! As to why
 +    // `.note.rustc` works on MinGW, that's another good question...
 +
      if target.options.is_like_osx {
 -        "__DATA,__note.rustc"
 -    } else if target.options.is_like_msvc {
 -        // When using link.exe it was seen that the section name `.note.rustc`
 -        // was getting shortened to `.note.ru`, and according to the PE and COFF
 -        // specification:
 -        //
 -        // > Executable images do not use a string table and do not support
 -        // > section names longer than 8 characters
 -        //
 -        // https://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx
 -        //
 -        // As a result, we choose a slightly shorter name! As to why
 -        // `.note.rustc` works on MinGW, that's another good question...
 -        ".rustc"
 +        "__DATA,.rustc"
      } else {
 -        ".note.rustc"
 +        ".rustc"
      }
  }
  
 -pub fn read_meta_section_name(target: &Target) -> &'static str {
 -    if target.options.is_like_osx {
 -        "__note.rustc"
 -    } else if target.options.is_like_msvc {
 -        ".rustc"
 -    } else {
 -        ".note.rustc"
 -    }
 +pub fn read_meta_section_name(_target: &Target) -> &'static str {
 +    ".rustc"
  }
  
  // A diagnostic function for dumping crate metadata to an output stream
index df893842337c47a36ff4ab851ea951d550737420,a79eca15a369a2cb81a8e93bb31247e573c0abf3..30618ff37273569ba6251f5780d76ae3dae1ad51
@@@ -2250,17 -2250,10 +2250,17 @@@ fn write_metadata(cx: &SharedCrateConte
      };
      unsafe {
          llvm::LLVMSetInitializer(llglobal, llconst);
 -        let name =
 +        let section_name =
              cx.tcx().sess.cstore.metadata_section_name(&cx.sess().target.target);
 -        let name = CString::new(name).unwrap();
 -        llvm::LLVMSetSection(llglobal, name.as_ptr())
 +        let name = CString::new(section_name).unwrap();
 +        llvm::LLVMSetSection(llglobal, name.as_ptr());
 +
 +        // Also generate a .section directive to force no
 +        // flags, at least for ELF outputs, so that the
 +        // metadata doesn't get loaded into memory.
 +        let directive = format!(".section {}", section_name);
 +        let directive = CString::new(directive).unwrap();
 +        llvm::LLVMSetModuleInlineAsm(cx.metadata_llmod(), directive.as_ptr())
      }
      return metadata;
  }
@@@ -2576,7 -2569,7 +2576,7 @@@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtx
      assert_module_sources::assert_module_sources(tcx, &modules);
  
      // Skip crate items and just output metadata in -Z no-trans mode.
-     if tcx.sess.opts.no_trans {
+     if tcx.sess.opts.debugging_opts.no_trans {
          let linker_info = LinkerInfo::new(&shared_ccx, &[]);
          return CrateTranslation {
              modules: modules,
index afda59c61ff76246b99a2bdc2458d07761d2ebfb,d7a6c16ede0ce3e6a2ba4fde15de6aec48ed415a..a6f0e0ca31e3e4fa94dec928990daab430ac29df
@@@ -277,14 -277,7 +277,14 @@@ declare_features! 
      (active, cfg_target_has_atomic, "1.9.0", Some(32976)),
  
      // Allows `..` in tuple (struct) patterns
 -    (active, dotdot_in_tuple_patterns, "1.10.0", Some(33627))
 +    (active, dotdot_in_tuple_patterns, "1.10.0", Some(33627)),
 +
 +    // Allows `impl Trait` in function return types.
 +    (active, conservative_impl_trait, "1.12.0", Some(34511)),
 +
 +    // Allows tuple structs and variants in more contexts,
 +    // Permits numeric fields in struct expressions and patterns.
 +    (active, relaxed_adts, "1.12.0", Some(35626))
  );
  
  declare_features! (
@@@ -314,7 -307,7 +314,7 @@@ declare_features! 
      (accepted, issue_5723_bootstrap, "1.0.0", None),
      (accepted, macro_rules, "1.0.0", None),
      // Allows using #![no_std]
 -    (accepted, no_std, "1.0.0", None),
 +    (accepted, no_std, "1.6.0", None),
      (accepted, slicing_syntax, "1.0.0", None),
      (accepted, struct_variant, "1.0.0", None),
      // These are used to test this portion of the compiler, they don't actually
@@@ -959,10 -952,6 +959,10 @@@ impl<'a> Visitor for PostExpansionVisit
              ast::TyKind::BareFn(ref bare_fn_ty) => {
                  self.check_abi(bare_fn_ty.abi, ty.span);
              }
 +            ast::TyKind::ImplTrait(..) => {
 +                gate_feature_post!(&self, conservative_impl_trait, ty.span,
 +                                   "`impl Trait` is experimental");
 +            }
              _ => {}
          }
          visit::walk_ty(self, ty)
              }
              PatKind::TupleStruct(_, ref fields, ddpos)
                      if ddpos.is_none() && fields.is_empty() => {
 -                self.context.span_handler.struct_span_err(pattern.span,
 -                                                          "nullary enum variants are written with \
 -                                                           no trailing `( )`").emit();
 +                gate_feature_post!(&self, relaxed_adts, pattern.span,
 +                                   "empty tuple structs patterns are unstable");
              }
              _ => {}
          }
          visit::walk_impl_item(self, ii);
      }
  
 +    fn visit_variant_data(&mut self, vdata: &ast::VariantData, _: ast::Ident,
 +                          _: &ast::Generics, _: NodeId, span: Span) {
 +        if vdata.fields().is_empty() {
 +            if vdata.is_tuple() {
 +                gate_feature_post!(&self, relaxed_adts, span,
 +                                   "empty tuple structs and enum variants are unstable, \
 +                                    use unit structs and enum variants instead");
 +            }
 +        }
 +
 +        visit::walk_struct_def(self, vdata)
 +    }
 +
      fn visit_vis(&mut self, vis: &ast::Visibility) {
          let span = match *vis {
              ast::Visibility::Crate(span) => span,
@@@ -1194,7 -1171,7 +1194,7 @@@ pub fn check_crate(krate: &ast::Crate
      visit::walk_crate(&mut PostExpansionVisitor { context: &ctx }, krate);
  }
  
- #[derive(Clone, Copy)]
+ #[derive(Clone, Copy, PartialEq, Eq, Hash)]
  pub enum UnstableFeatures {
      /// Hard errors for unstable features are active, as on
      /// beta/stable channels.
index e9ccc029bc3cf4ee0efcfbef5d64ab94882edc54,c5413e3722830ce4a14540ff2158d88ba0f3e747..0d081b267bb7084301f001f4a3f61861b8b7ddf3
@@@ -137,6 -137,10 +137,6 @@@ impl<'test> TestCx<'test> 
  
          self.check_correct_failure_status(&proc_res);
  
 -        if proc_res.status.success() {
 -            self.fatal("process did not return an error status");
 -        }
 -
          let output_to_check = self.get_output(&proc_res);
          let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
          if !expected_errors.is_empty() {
@@@ -2008,6 -2012,7 +2008,7 @@@ actual:\n
          // Add an extra flag pointing at the incremental directory.
          let mut revision_props = self.props.clone();
          revision_props.incremental_dir = Some(incremental_dir);
+         revision_props.compile_flags.push(String::from("-Zincremental-info"));
  
          let revision_cx = TestCx {
              config: self.config,