11#![ doc( html_root_url = "https://doc.rust-lang.org/nightly/" ) ]
22#![ feature( nll) ]
33#![ feature( or_patterns) ]
4+ #![ cfg_attr( bootstrap, feature( track_caller) ) ]
45#![ recursion_limit = "256" ]
56
67mod dump_visitor;
@@ -47,12 +48,9 @@ use rls_data::{
4748
4849use log:: { debug, error, info} ;
4950
50- pub struct SaveContext < ' l , ' tcx > {
51+ pub struct SaveContext < ' l , ' tcx : ' l > {
5152 tcx : TyCtxt < ' tcx > ,
52- tables : & ' l ty:: TypeckTables < ' tcx > ,
53- /// Used as a fallback when nesting the typeck tables during item processing
54- /// (if these are not available for that item, e.g. don't own a body)
55- empty_tables : & ' l ty:: TypeckTables < ' tcx > ,
53+ maybe_typeck_tables : Option < & ' tcx ty:: TypeckTables < ' tcx > > ,
5654 access_levels : & ' l AccessLevels ,
5755 span_utils : SpanUtils < ' tcx > ,
5856 config : Config ,
@@ -67,6 +65,14 @@ pub enum Data {
6765}
6866
6967impl < ' l , ' tcx > SaveContext < ' l , ' tcx > {
68+ /// Gets the type-checking side-tables for the current body.
69+ /// As this will ICE if called outside bodies, only call when working with
70+ /// `Expr` or `Pat` nodes (they are guaranteed to be found only in bodies).
71+ #[ track_caller]
72+ fn tables ( & self ) -> & ' tcx ty:: TypeckTables < ' tcx > {
73+ self . maybe_typeck_tables . expect ( "`SaveContext::tables` called outside of body" )
74+ }
75+
7076 fn span_from_span ( & self , span : Span ) -> SpanData {
7177 use rls_span:: { Column , Row } ;
7278
@@ -518,13 +524,13 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
518524 }
519525
520526 pub fn get_expr_data ( & self , expr : & hir:: Expr < ' _ > ) -> Option < Data > {
521- let ty = self . tables . expr_ty_adjusted_opt ( expr) ?;
527+ let ty = self . tables ( ) . expr_ty_adjusted_opt ( expr) ?;
522528 if matches ! ( ty. kind, ty:: Error ( _) ) {
523529 return None ;
524530 }
525531 match expr. kind {
526532 hir:: ExprKind :: Field ( ref sub_ex, ident) => {
527- match self . tables . expr_ty_adjusted ( & sub_ex) . kind {
533+ match self . tables ( ) . expr_ty_adjusted ( & sub_ex) . kind {
528534 ty:: Adt ( def, _) if !def. is_enum ( ) => {
529535 let variant = & def. non_enum_variant ( ) ;
530536 filter ! ( self . span_utils, ident. span) ;
@@ -569,7 +575,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
569575 }
570576 }
571577 hir:: ExprKind :: MethodCall ( ref seg, ..) => {
572- let method_id = match self . tables . type_dependent_def_id ( expr. hir_id ) {
578+ let method_id = match self . tables ( ) . type_dependent_def_id ( expr. hir_id ) {
573579 Some ( id) => id,
574580 None => {
575581 debug ! ( "could not resolve method id for {:?}" , expr) ;
@@ -618,7 +624,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
618624 } ,
619625
620626 Node :: Expr ( & hir:: Expr { kind : hir:: ExprKind :: Struct ( ref qpath, ..) , .. } ) => {
621- self . tables . qpath_res ( qpath, hir_id)
627+ self . tables ( ) . qpath_res ( qpath, hir_id)
622628 }
623629
624630 Node :: Expr ( & hir:: Expr { kind : hir:: ExprKind :: Path ( ref qpath) , .. } )
@@ -629,9 +635,12 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
629635 | hir:: PatKind :: TupleStruct ( ref qpath, ..) ,
630636 ..
631637 } )
632- | Node :: Ty ( & hir:: Ty { kind : hir:: TyKind :: Path ( ref qpath) , .. } ) => {
633- self . tables . qpath_res ( qpath, hir_id)
634- }
638+ | Node :: Ty ( & hir:: Ty { kind : hir:: TyKind :: Path ( ref qpath) , .. } ) => match qpath {
639+ hir:: QPath :: Resolved ( _, path) => path. res ,
640+ hir:: QPath :: TypeRelative ( ..) => self
641+ . maybe_typeck_tables
642+ . map_or ( Res :: Err , |tables| tables. qpath_res ( qpath, hir_id) ) ,
643+ } ,
635644
636645 Node :: Binding ( & hir:: Pat {
637646 kind : hir:: PatKind :: Binding ( _, canonical_id, ..) , ..
@@ -1001,8 +1010,7 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>(
10011010
10021011 let save_ctxt = SaveContext {
10031012 tcx,
1004- tables : & ty:: TypeckTables :: empty ( None ) ,
1005- empty_tables : & ty:: TypeckTables :: empty ( None ) ,
1013+ maybe_typeck_tables : None ,
10061014 access_levels : & access_levels,
10071015 span_utils : SpanUtils :: new ( & tcx. sess ) ,
10081016 config : find_config ( config) ,
0 commit comments