@@ -19,43 +19,68 @@ use rustc_session::{output::find_crate_name, Session};
19
19
use rustc_span:: symbol:: sym;
20
20
use rustc_span:: Symbol ;
21
21
use std:: any:: Any ;
22
- use std:: cell:: { Ref , RefCell , RefMut } ;
22
+ use std:: cell:: { Ref , RefCell } ;
23
23
use std:: rc:: Rc ;
24
24
use std:: sync:: Arc ;
25
25
26
26
/// Represent the result of a query.
27
27
///
28
- /// This result can be stolen with the [`take`] method and generated with the [`compute`] method.
28
+ /// This result can be stolen once with the [`take`] method and generated with the [`compute`] method.
29
29
///
30
30
/// [`take`]: Self::take
31
31
/// [`compute`]: Self::compute
32
32
pub struct Query < T > {
33
- result : RefCell < Option < Result < T > > > ,
33
+ result : RefCell < Option < Option < Result < T > > > > ,
34
34
}
35
35
36
36
impl < T > Query < T > {
37
37
fn compute < F : FnOnce ( ) -> Result < T > > ( & self , f : F ) -> Result < & Query < T > > {
38
- self . result . borrow_mut ( ) . get_or_insert_with ( f) . as_ref ( ) . map ( |_| self ) . map_err ( |& err| err)
38
+ self . result
39
+ . borrow_mut ( )
40
+ . get_or_insert_with ( || Some ( f ( ) ) )
41
+ . as_ref ( )
42
+ . expect ( "query already taken" )
43
+ . as_ref ( )
44
+ . map ( |_| self )
45
+ . map_err ( |& err| err)
39
46
}
40
47
41
48
/// Takes ownership of the query result. Further attempts to take or peek the query
42
49
/// result will panic unless it is generated by calling the `compute` method.
43
50
pub fn take ( & self ) -> T {
44
- self . result . borrow_mut ( ) . take ( ) . expect ( "missing query result" ) . unwrap ( )
51
+ self . result
52
+ . borrow_mut ( )
53
+ . as_mut ( )
54
+ . expect ( "query never computed" )
55
+ . take ( )
56
+ . expect ( "query already taken" )
57
+ . unwrap ( )
45
58
}
46
59
47
60
/// Borrows the query result using the RefCell. Panics if the result is stolen.
48
61
pub fn peek ( & self ) -> Ref < ' _ , T > {
49
62
Ref :: map ( self . result . borrow ( ) , |r| {
50
- r. as_ref ( ) . unwrap ( ) . as_ref ( ) . expect ( "missing query result" )
63
+ r. as_ref ( )
64
+ . unwrap ( )
65
+ . as_ref ( )
66
+ . expect ( "query never computed" )
67
+ . as_ref ( )
68
+ . expect ( "query already taken" )
51
69
} )
52
70
}
71
+ }
53
72
54
- /// Mutably borrows the query result using the RefCell. Panics if the result is stolen.
55
- pub fn peek_mut ( & self ) -> RefMut < ' _ , T > {
56
- RefMut :: map ( self . result . borrow_mut ( ) , |r| {
57
- r. as_mut ( ) . unwrap ( ) . as_mut ( ) . expect ( "missing query result" )
58
- } )
73
+ impl < ' tcx > Query < QueryContext < ' tcx > > {
74
+ pub fn enter < T > ( & self , f : impl FnOnce ( TyCtxt < ' tcx > ) -> T ) -> T {
75
+ self . result
76
+ . borrow_mut ( )
77
+ . as_mut ( )
78
+ . unwrap ( )
79
+ . as_mut ( )
80
+ . expect ( "query never computed" )
81
+ . as_mut ( )
82
+ . expect ( "query already taken" )
83
+ . enter ( f)
59
84
}
60
85
}
61
86
@@ -237,7 +262,7 @@ impl<'tcx> Queries<'tcx> {
237
262
238
263
pub fn ongoing_codegen ( & ' tcx self ) -> Result < & Query < Box < dyn Any > > > {
239
264
self . ongoing_codegen . compute ( || {
240
- self . global_ctxt ( ) ?. peek_mut ( ) . enter ( |tcx| {
265
+ self . global_ctxt ( ) ?. enter ( |tcx| {
241
266
tcx. analysis ( ( ) ) . ok ( ) ;
242
267
243
268
// Don't do code generation if there were any errors
@@ -296,7 +321,6 @@ impl<'tcx> Queries<'tcx> {
296
321
let dep_graph = self . dep_graph ( ) ?. peek ( ) . clone ( ) ;
297
322
let ( crate_hash, prepare_outputs) = self
298
323
. global_ctxt ( ) ?
299
- . peek_mut ( )
300
324
. enter ( |tcx| ( tcx. crate_hash ( LOCAL_CRATE ) , tcx. output_filenames ( ( ) ) . clone ( ) ) ) ;
301
325
let ongoing_codegen = self . ongoing_codegen ( ) ?. take ( ) ;
302
326
@@ -381,7 +405,7 @@ impl Compiler {
381
405
382
406
// NOTE: intentionally does not compute the global context if it hasn't been built yet,
383
407
// since that likely means there was a parse error.
384
- if let Some ( Ok ( gcx) ) = & mut * queries. global_ctxt . result . borrow_mut ( ) {
408
+ if let Some ( Some ( Ok ( gcx) ) ) = & mut * queries. global_ctxt . result . borrow_mut ( ) {
385
409
// We assume that no queries are run past here. If there are new queries
386
410
// after this point, they'll show up as "<unknown>" in self-profiling data.
387
411
{
0 commit comments