@@ -33,10 +33,11 @@ use syntax::feature_gate::AttributeType;
3333use syntax_pos:: { Span , MultiSpan } ;
3434
3535use rustc_back:: target:: Target ;
36+ use rustc_data_structures:: flock;
3637use llvm;
3738
3839use std:: path:: { Path , PathBuf } ;
39- use std:: cell:: { Cell , RefCell } ;
40+ use std:: cell:: { self , Cell , RefCell } ;
4041use std:: collections:: { HashMap , HashSet } ;
4142use std:: env;
4243use std:: ffi:: CString ;
@@ -101,6 +102,8 @@ pub struct Session {
101102 /// macro name and defintion span in the source crate.
102103 pub imported_macro_spans : RefCell < HashMap < Span , ( String , Span ) > > ,
103104
105+ incr_comp_session : RefCell < IncrCompSession > ,
106+
104107 next_node_id : Cell < ast:: NodeId > ,
105108}
106109
@@ -331,6 +334,76 @@ impl Session {
331334 & self . opts . search_paths ,
332335 kind)
333336 }
337+
338+ pub fn init_incr_comp_session ( & self ,
339+ session_dir : PathBuf ,
340+ lock_file : flock:: Lock ) {
341+ let mut incr_comp_session = self . incr_comp_session . borrow_mut ( ) ;
342+
343+ if let IncrCompSession :: NotInitialized = * incr_comp_session { } else {
344+ bug ! ( "Trying to initialize IncrCompSession `{:?}`" , * incr_comp_session)
345+ }
346+
347+ * incr_comp_session = IncrCompSession :: Active {
348+ session_directory : session_dir,
349+ lock_file : lock_file,
350+ } ;
351+ }
352+
353+ pub fn finalize_incr_comp_session ( & self , new_directory_path : PathBuf ) {
354+ let mut incr_comp_session = self . incr_comp_session . borrow_mut ( ) ;
355+
356+ if let IncrCompSession :: Active { .. } = * incr_comp_session { } else {
357+ bug ! ( "Trying to finalize IncrCompSession `{:?}`" , * incr_comp_session)
358+ }
359+
360+ // Note: This will also drop the lock file, thus unlocking the directory
361+ * incr_comp_session = IncrCompSession :: Finalized {
362+ session_directory : new_directory_path,
363+ } ;
364+ }
365+
366+ pub fn mark_incr_comp_session_as_invalid ( & self ) {
367+ let mut incr_comp_session = self . incr_comp_session . borrow_mut ( ) ;
368+
369+ let session_directory = match * incr_comp_session {
370+ IncrCompSession :: Active { ref session_directory, .. } => {
371+ session_directory. clone ( )
372+ }
373+ _ => bug ! ( "Trying to invalidate IncrCompSession `{:?}`" ,
374+ * incr_comp_session) ,
375+ } ;
376+
377+ // Note: This will also drop the lock file, thus unlocking the directory
378+ * incr_comp_session = IncrCompSession :: InvalidBecauseOfErrors {
379+ session_directory : session_directory
380+ } ;
381+ }
382+
383+ pub fn incr_comp_session_dir ( & self ) -> cell:: Ref < PathBuf > {
384+ let incr_comp_session = self . incr_comp_session . borrow ( ) ;
385+ cell:: Ref :: map ( incr_comp_session, |incr_comp_session| {
386+ match * incr_comp_session {
387+ IncrCompSession :: NotInitialized => {
388+ bug ! ( "Trying to get session directory from IncrCompSession `{:?}`" ,
389+ * incr_comp_session)
390+ }
391+ IncrCompSession :: Active { ref session_directory, .. } |
392+ IncrCompSession :: Finalized { ref session_directory } |
393+ IncrCompSession :: InvalidBecauseOfErrors { ref session_directory } => {
394+ session_directory
395+ }
396+ }
397+ } )
398+ }
399+
400+ pub fn incr_comp_session_dir_opt ( & self ) -> Option < cell:: Ref < PathBuf > > {
401+ if self . opts . incremental . is_some ( ) {
402+ Some ( self . incr_comp_session_dir ( ) )
403+ } else {
404+ None
405+ }
406+ }
334407}
335408
336409pub fn build_session ( sopts : config:: Options ,
@@ -446,13 +519,39 @@ pub fn build_session_(sopts: config::Options,
446519 injected_panic_runtime : Cell :: new ( None ) ,
447520 available_macros : RefCell :: new ( HashSet :: new ( ) ) ,
448521 imported_macro_spans : RefCell :: new ( HashMap :: new ( ) ) ,
522+ incr_comp_session : RefCell :: new ( IncrCompSession :: NotInitialized ) ,
449523 } ;
450524
451525 init_llvm ( & sess) ;
452526
453527 sess
454528}
455529
530+ /// Holds data on the current incremental compilation session, if there is one.
531+ #[ derive( Debug ) ]
532+ pub enum IncrCompSession {
533+ // This is the state the session will be in until the incr. comp. dir is
534+ // needed.
535+ NotInitialized ,
536+ // This is the state during which the session directory is private and can
537+ // be modified.
538+ Active {
539+ session_directory : PathBuf ,
540+ lock_file : flock:: Lock ,
541+ } ,
542+ // This is the state after the session directory has been finalized. In this
543+ // state, the contents of the directory must not be modified any more.
544+ Finalized {
545+ session_directory : PathBuf ,
546+ } ,
547+ // This is an error state that is reached when some compilation error has
548+ // occurred. It indicates that the contents of the session directory must
549+ // not be used, since they might be invalid.
550+ InvalidBecauseOfErrors {
551+ session_directory : PathBuf ,
552+ }
553+ }
554+
456555fn init_llvm ( sess : & Session ) {
457556 unsafe {
458557 // Before we touch LLVM, make sure that multithreading is enabled.
0 commit comments