@@ -1489,10 +1489,13 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
14891489
14901490impl < ' gcx : ' tcx , ' tcx > GlobalCtxt < ' gcx > {
14911491 /// Call the closure with a local `TyCtxt` using the given arena.
1492- pub fn enter_local < F , R > ( & self ,
1493- arena : & ' tcx DroplessArena ,
1494- f : F ) -> R
1495- where F : for < ' a > FnOnce ( TyCtxt < ' a , ' gcx , ' tcx > ) -> R
1492+ pub fn enter_local < F , R > (
1493+ & self ,
1494+ arena : & ' tcx DroplessArena ,
1495+ f : F
1496+ ) -> R
1497+ where
1498+ F : for < ' a > FnOnce ( TyCtxt < ' a , ' gcx , ' tcx > ) -> R
14961499 {
14971500 let interners = CtxtInterners :: new ( arena) ;
14981501 let tcx = TyCtxt {
@@ -1665,12 +1668,23 @@ pub mod tls {
16651668 use rustc_data_structures:: OnDrop ;
16661669 use rustc_data_structures:: sync:: Lrc ;
16671670
1671+ /// This is the implicit state of rustc. It contains the current
1672+ /// TyCtxt and query. It is updated when creating a local interner or
1673+ /// executing a new query. Whenever there's a TyCtxt value available
1674+ /// you should also have access to an ImplicitCtxt through the functions
1675+ /// in this module.
16681676 #[ derive( Clone ) ]
16691677 pub struct ImplicitCtxt < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
1678+ /// The current TyCtxt. Initially created by `enter_global` and updated
1679+ /// by `enter_local` with a new local interner
16701680 pub tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
1681+
1682+ /// The current query job, if any. This is updated by start_job in
1683+ /// ty::maps::plumbing when executing a query
16711684 pub query : Option < Lrc < maps:: QueryJob < ' gcx > > > ,
16721685 }
16731686
1687+ // A thread local value which stores a pointer to the current ImplicitCtxt
16741688 thread_local ! ( static TLV : Cell <usize > = Cell :: new( 0 ) ) ;
16751689
16761690 fn set_tlv < F : FnOnce ( ) -> R , R > ( value : usize , f : F ) -> R {
@@ -1684,12 +1698,17 @@ pub mod tls {
16841698 TLV . with ( |tlv| tlv. get ( ) )
16851699 }
16861700
1701+ /// This is a callback from libsyntax as it cannot access the implicit state
1702+ /// in librustc otherwise
16871703 fn span_debug ( span : syntax_pos:: Span , f : & mut fmt:: Formatter ) -> fmt:: Result {
16881704 with ( |tcx| {
16891705 write ! ( f, "{}" , tcx. sess. codemap( ) . span_to_string( span) )
16901706 } )
16911707 }
16921708
1709+ /// This is a callback from libsyntax as it cannot access the implicit state
1710+ /// in librustc otherwise. It is used to when diagnostic messages are
1711+ /// emitted and stores them in the current query, if there is one.
16931712 fn track_diagnostic ( diagnostic : & Diagnostic ) {
16941713 with_context ( |context| {
16951714 if let Some ( ref query) = context. query {
@@ -1698,6 +1717,7 @@ pub mod tls {
16981717 } )
16991718 }
17001719
1720+ /// Sets up the callbacks from libsyntax on the current thread
17011721 pub fn with_thread_locals < F , R > ( f : F ) -> R
17021722 where F : FnOnce ( ) -> R
17031723 {
@@ -1722,6 +1742,20 @@ pub mod tls {
17221742 } )
17231743 }
17241744
1745+ /// Sets `context` as the new current ImplicitCtxt for the duration of the function `f`
1746+ pub fn enter_context < ' a , ' gcx : ' tcx , ' tcx , F , R > ( context : & ImplicitCtxt < ' a , ' gcx , ' tcx > ,
1747+ f : F ) -> R
1748+ where F : FnOnce ( & ImplicitCtxt < ' a , ' gcx , ' tcx > ) -> R
1749+ {
1750+ set_tlv ( context as * const _ as usize , || {
1751+ f ( & context)
1752+ } )
1753+ }
1754+
1755+ /// Enters GlobalCtxt by setting up libsyntax callbacks and
1756+ /// creating a initial TyCtxt and ImplicitCtxt.
1757+ /// This happens once per rustc session and TyCtxts only exists
1758+ /// inside the `f` function.
17251759 pub fn enter_global < ' gcx , F , R > ( gcx : & GlobalCtxt < ' gcx > , f : F ) -> R
17261760 where F : for < ' a > FnOnce ( TyCtxt < ' a , ' gcx , ' gcx > ) -> R
17271761 {
@@ -1740,15 +1774,7 @@ pub mod tls {
17401774 } )
17411775 }
17421776
1743- pub fn enter_context < ' a , ' gcx : ' tcx , ' tcx , F , R > ( context : & ImplicitCtxt < ' a , ' gcx , ' tcx > ,
1744- f : F ) -> R
1745- where F : FnOnce ( & ImplicitCtxt < ' a , ' gcx , ' tcx > ) -> R
1746- {
1747- set_tlv ( context as * const _ as usize , || {
1748- f ( & context)
1749- } )
1750- }
1751-
1777+ /// Allows access to the current ImplicitCtxt in a closure if one is available
17521778 pub fn with_context_opt < F , R > ( f : F ) -> R
17531779 where F : for <' a , ' gcx , ' tcx > FnOnce ( Option < & ImplicitCtxt < ' a , ' gcx , ' tcx > > ) -> R
17541780 {
@@ -1760,46 +1786,62 @@ pub mod tls {
17601786 }
17611787 }
17621788
1763- pub fn with_fully_related_context < ' a , ' gcx , ' tcx , F , R > ( tcx : TyCtxt < ' a , ' gcx , ' tcx > , f : F ) -> R
1764- where F : for < ' b > FnOnce ( & ImplicitCtxt < ' b , ' gcx , ' tcx > ) -> R
1789+ /// Allows access to the current ImplicitCtxt.
1790+ /// Panics if there is no ImplicitCtxt available
1791+ pub fn with_context < F , R > ( f : F ) -> R
1792+ where F : for <' a , ' gcx , ' tcx > FnOnce ( & ImplicitCtxt < ' a , ' gcx , ' tcx > ) -> R
1793+ {
1794+ with_context_opt ( |opt_context| f ( opt_context. expect ( "no ImplicitCtxt stored in tls" ) ) )
1795+ }
1796+
1797+ /// Allows access to the current ImplicitCtxt whose tcx field has the same global
1798+ /// interner as the tcx argument passed in. This means the closure is given an ImplicitCtxt
1799+ /// with the same 'gcx lifetime as the TyCtxt passed in.
1800+ /// This will panic if you pass it a TyCtxt which has a different global interner from
1801+ /// the current ImplicitCtxt's tcx field.
1802+ pub fn with_related_context < ' a , ' gcx , ' tcx1 , F , R > ( tcx : TyCtxt < ' a , ' gcx , ' tcx1 > , f : F ) -> R
1803+ where F : for <' b , ' tcx2 > FnOnce ( & ImplicitCtxt < ' b , ' gcx , ' tcx2 > ) -> R
17651804 {
17661805 with_context ( |context| {
17671806 unsafe {
17681807 let gcx = tcx. gcx as * const _ as usize ;
1769- let interners = tcx. interners as * const _ as usize ;
17701808 assert ! ( context. tcx. gcx as * const _ as usize == gcx) ;
1771- assert ! ( context. tcx. interners as * const _ as usize == interners) ;
17721809 let context: & ImplicitCtxt = mem:: transmute ( context) ;
17731810 f ( context)
17741811 }
17751812 } )
17761813 }
17771814
1778- pub fn with_related_context < ' a , ' gcx , ' tcx1 , F , R > ( tcx : TyCtxt < ' a , ' gcx , ' tcx1 > , f : F ) -> R
1779- where F : for <' b , ' tcx2 > FnOnce ( & ImplicitCtxt < ' b , ' gcx , ' tcx2 > ) -> R
1815+ /// Allows access to the current ImplicitCtxt whose tcx field has the same global
1816+ /// interner and local interner as the tcx argument passed in. This means the closure
1817+ /// is given an ImplicitCtxt with the same 'tcx and 'gcx lifetimes as the TyCtxt passed in.
1818+ /// This will panic if you pass it a TyCtxt which has a different global interner or
1819+ /// a different local interner from the current ImplicitCtxt's tcx field.
1820+ pub fn with_fully_related_context < ' a , ' gcx , ' tcx , F , R > ( tcx : TyCtxt < ' a , ' gcx , ' tcx > , f : F ) -> R
1821+ where F : for < ' b > FnOnce ( & ImplicitCtxt < ' b , ' gcx , ' tcx > ) -> R
17801822 {
17811823 with_context ( |context| {
17821824 unsafe {
17831825 let gcx = tcx. gcx as * const _ as usize ;
1826+ let interners = tcx. interners as * const _ as usize ;
17841827 assert ! ( context. tcx. gcx as * const _ as usize == gcx) ;
1828+ assert ! ( context. tcx. interners as * const _ as usize == interners) ;
17851829 let context: & ImplicitCtxt = mem:: transmute ( context) ;
17861830 f ( context)
17871831 }
17881832 } )
17891833 }
17901834
1791- pub fn with_context < F , R > ( f : F ) -> R
1792- where F : for <' a , ' gcx , ' tcx > FnOnce ( & ImplicitCtxt < ' a , ' gcx , ' tcx > ) -> R
1793- {
1794- with_context_opt ( |opt_context| f ( opt_context. expect ( "no ImplicitCtxt stored in tls" ) ) )
1795- }
1796-
1835+ /// Allows access to the TyCtxt in the current ImplicitCtxt.
1836+ /// Panics if there is no ImplicitCtxt available
17971837 pub fn with < F , R > ( f : F ) -> R
17981838 where F : for <' a , ' gcx , ' tcx > FnOnce ( TyCtxt < ' a , ' gcx , ' tcx > ) -> R
17991839 {
18001840 with_context ( |context| f ( context. tcx ) )
18011841 }
18021842
1843+ /// Allows access to the TyCtxt in the current ImplicitCtxt.
1844+ /// The closure is passed None if there is no ImplicitCtxt available
18031845 pub fn with_opt < F , R > ( f : F ) -> R
18041846 where F : for <' a , ' gcx , ' tcx > FnOnce ( Option < TyCtxt < ' a , ' gcx , ' tcx > > ) -> R
18051847 {
0 commit comments