1+ use std:: cell:: LazyCell ;
2+
13use marker_adapter:: Adapter ;
4+ use marker_api:: lint:: Lint ;
25
36use crate :: context:: { storage:: Storage , RustcContext } ;
47
5- pub struct MarkerLintPass ;
8+ thread_local ! {
9+ /// The [`Adapter`] loads the lint crates and is the general interface used
10+ /// by drivers to communicate with lint crates.
11+ ///
12+ /// The lint crates have to be loaded before the instantiation of [`RustcLintPass`]
13+ /// to allow this driver to register the lints before the lint pass starts.
14+ /// (See [`super::MarkerCallback::config`]). Storing the `Adapter` in a `thread_local`
15+ /// cell is the easiest solution I could come up with. It should be fine performance
16+ /// wise.
17+ ///
18+ /// Storing the [`Adapter`] in a `thread_local` is safe, since rustc is currently
19+ /// only single threaded. This cell will therefore only be constructed once, and
20+ /// this driver will always use the same adapter.
21+ static ADAPTER : LazyCell <Adapter > = LazyCell :: new( || {
22+ Adapter :: new_from_env( )
23+ } ) ;
24+ }
25+
26+ pub struct RustcLintPass ;
27+
28+ impl RustcLintPass {
29+ pub fn marker_lints ( ) -> Vec < & ' static Lint > {
30+ ADAPTER . with ( |adapter| {
31+ adapter
32+ . lint_pass_infos ( )
33+ . iter ( )
34+ . flat_map ( marker_api:: LintPassInfo :: lints)
35+ . copied ( )
36+ . collect ( )
37+ } )
38+ }
39+ }
640
7- rustc_lint_defs:: impl_lint_pass!( MarkerLintPass => [ ] ) ;
41+ rustc_lint_defs:: impl_lint_pass!( RustcLintPass => [ ] ) ;
842
9- impl < ' tcx > rustc_lint:: LateLintPass < ' tcx > for MarkerLintPass {
43+ impl < ' tcx > rustc_lint:: LateLintPass < ' tcx > for RustcLintPass {
1044 fn check_crate ( & mut self , rustc_cx : & rustc_lint:: LateContext < ' tcx > ) {
11- process_crate ( rustc_cx) ;
45+ ADAPTER . with ( |adapter| {
46+ process_crate ( rustc_cx, adapter) ;
47+ } ) ;
1248 }
1349}
1450
15- fn process_crate ( rustc_cx : & rustc_lint:: LateContext < ' _ > ) {
51+ fn process_crate ( rustc_cx : & rustc_lint:: LateContext < ' _ > , adapter : & Adapter ) {
1652 let storage = Storage :: default ( ) ;
17- process_crate_lifetime ( rustc_cx, & storage) ;
53+ process_crate_lifetime ( rustc_cx, & storage, adapter ) ;
1854}
1955
2056/// This function marks the start of the `'ast` lifetime. The lifetime is defined
2157/// by the [`Storage`] object.
22- fn process_crate_lifetime < ' ast , ' tcx : ' ast > ( rustc_cx : & rustc_lint:: LateContext < ' tcx > , storage : & ' ast Storage < ' ast > ) {
58+ fn process_crate_lifetime < ' ast , ' tcx : ' ast > (
59+ rustc_cx : & rustc_lint:: LateContext < ' tcx > ,
60+ storage : & ' ast Storage < ' ast > ,
61+ adapter : & Adapter ,
62+ ) {
2363 let driver_cx = RustcContext :: new ( rustc_cx. tcx , rustc_cx. lint_store , storage) ;
2464
2565 // To support debug printing of AST nodes, as these might sometimes require the
@@ -31,6 +71,5 @@ fn process_crate_lifetime<'ast, 'tcx: 'ast>(rustc_cx: &rustc_lint::LateContext<'
3171 . marker_converter
3272 . to_crate ( rustc_hir:: def_id:: LOCAL_CRATE , driver_cx. rustc_cx . hir ( ) . root_module ( ) ) ;
3373
34- let mut adapter = Adapter :: new_from_env ( ) ;
3574 adapter. process_krate ( driver_cx. ast_cx ( ) , krate) ;
3675}
0 commit comments