@@ -251,6 +251,13 @@ fn hir_enclosing_body_owner(tcx: TyCtxt<'_>, hir_id: HirId) -> Option<LocalDefId
251251 return None ;
252252 } else if let Some ( ( def_id, _) ) = node. associated_body ( ) {
253253 return Some ( def_id) ;
254+ // Items don't have bodies.
255+ // If we go any further, we might encounter an enclosing function
256+ // (e.g. if we're inside an impl that's inside of a function).
257+ // This would cause us to erroneously consider this function to be the owner
258+ // of the node and produce invalid `HirId`s later.
259+ } else if matches ! ( node, Node :: Item ( _) ) {
260+ return None ;
254261 }
255262 }
256263 None
@@ -278,13 +285,22 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
278285 let tcx = self . tcx ;
279286 if let Some ( body_id) = hir_enclosing_body_owner ( tcx, id) {
280287 let typeck_results = tcx. typeck_body ( tcx. hir_body_owned_by ( body_id) . id ( ) ) ;
288+ let path_res =
289+ match std:: panic:: catch_unwind ( std:: panic:: AssertUnwindSafe ( || {
290+ typeck_results. qpath_res ( qpath, id)
291+ } ) ) {
292+ Ok ( path_res) => path_res,
293+ Err ( panic) => std:: panic:: resume_unwind ( panic) ,
294+ } ;
281295 let path = rustc_hir:: Path {
282296 // We change the span to not include parens.
283297 span : path. ident . span ,
284- res : typeck_results . qpath_res ( qpath , id ) ,
298+ res : path_res ,
285299 segments : & [ ] ,
286300 } ;
287301 self . handle_path ( & path, false ) ;
302+ } else {
303+ eprintln ! ( "can't find a body for {id:?} :(" ) ;
288304 }
289305 } else {
290306 self . infer_id ( path. hir_id , Some ( id) , path. ident . span . into ( ) ) ;
0 commit comments