@@ -715,12 +715,17 @@ impl Span {
715715        ( !ctxt. is_root ( ) ) . then ( || ctxt. outer_expn_data ( ) . call_site ) 
716716    } 
717717
718-     /// Walk down  the expansion ancestors to find a  span that's contained within `outer`. 
718+     /// Find  the first ancestor  span that's contained within `outer`. 
719719/// 
720- /// The span returned by this method may have a different [`SyntaxContext`] as `outer`. 
720+ /// This method traverses the macro expansion ancestors until it finds the first span 
721+ /// that's contained within `outer`. 
722+ /// 
723+ /// The span returned by this method may have a different [`SyntaxContext`] than `outer`. 
721724/// If you need to extend the span, use [`find_ancestor_inside_same_ctxt`] instead, 
722725/// because joining spans with different syntax contexts can create unexpected results. 
723726/// 
727+ /// This is used to find the span of the macro call when a parent expr span, i.e. `outer`, is known. 
728+ /// 
724729/// [`find_ancestor_inside_same_ctxt`]: Self::find_ancestor_inside_same_ctxt 
725730pub  fn  find_ancestor_inside ( mut  self ,  outer :  Span )  -> Option < Span >  { 
726731        while  !outer. contains ( self )  { 
@@ -729,8 +734,10 @@ impl Span {
729734        Some ( self ) 
730735    } 
731736
732-     /// Walk down the expansion ancestors to find a span with the same [`SyntaxContext`] as 
733- /// `other`. 
737+     /// Find the first ancestor span with the same [`SyntaxContext`] as `other`. 
738+ /// 
739+ /// This method traverses the macro expansion ancestors until it finds a span 
740+ /// that has the same [`SyntaxContext`] as `other`. 
734741/// 
735742/// Like [`find_ancestor_inside_same_ctxt`], but specifically for when spans might not 
736743/// overlap. Take care when using this, and prefer [`find_ancestor_inside`] or 
@@ -746,9 +753,12 @@ impl Span {
746753        Some ( self ) 
747754    } 
748755
749-     /// Walk down  the expansion ancestors to find a  span that's contained within `outer` and 
756+     /// Find  the first ancestor  span that's contained within `outer` and 
750757/// has the same [`SyntaxContext`] as `outer`. 
751758/// 
759+ /// This method traverses the macro expansion ancestors until it finds a span 
760+ /// that is both contained within `outer` and has the same [`SyntaxContext`] as `outer`. 
761+ /// 
752762/// This method is the combination of [`find_ancestor_inside`] and 
753763/// [`find_ancestor_in_same_ctxt`] and should be preferred when extending the returned span. 
754764/// If you do not need to modify the span, use [`find_ancestor_inside`] instead. 
@@ -762,43 +772,43 @@ impl Span {
762772        Some ( self ) 
763773    } 
764774
765-     /// Recursively walk down the expansion ancestors to find the oldest ancestor span with the same 
766- /// [`SyntaxContext`] the initial span. 
775+     /// Find the first ancestor span that does not come from an external macro. 
767776/// 
768- /// This method is suitable for peeling through *local* macro expansions to find the "innermost"  
769- /// span  that is still local and shares the same [`SyntaxContext`]. For example, given  
777+ /// This method traverses the macro expansion ancestors until it finds a span  
778+ /// that is either from user-written code or from a local macro (defined in the current crate).  
770779/// 
771- /// ```ignore (illustrative example, contains type error) 
772- ///  macro_rules! outer { 
773- ///      ($x: expr) => { 
774- ///          inner!($x) 
775- ///      } 
776- ///  } 
780+ /// External macros are those defined in dependencies or the standard library. 
781+ /// This method is useful for reporting errors in user-controllable code and avoiding 
782+ /// diagnostics inside external macros. 
777783/// 
778- ///  macro_rules! inner { 
779- ///      ($x: expr) => { 
780- ///          format!("error: {}", $x) 
781- ///          //~^ ERROR mismatched types 
782- ///      } 
783- ///  } 
784+ /// # See also 
784785/// 
785- ///  fn bar(x: &str) -> Result<(), Box<dyn std::error::Error>> { 
786- ///      Err(outer!(x)) 
787- ///  } 
788- /// ``` 
786+ /// - [`find_ancestor_not_from_macro`]: Finds ancestors not from any macro (local or external) 
787+ /// - [`Span::in_external_macro`]: Checks if a span comes from an external macro 
788+ pub  fn  find_ancestor_not_from_extern_macro ( mut  self ,  sm :  & SourceMap )  -> Option < Span >  { 
789+         while  self . in_external_macro ( sm)  { 
790+             self  = self . parent_callsite ( ) ?; 
791+         } 
792+         Some ( self ) 
793+     } 
794+ 
795+     /// Find the first ancestor span that does not come from any macro expansion. 
789796/// 
790- /// if provided the initial span of `outer!(x)` inside `bar`, this method will recurse 
791- /// the parent callsites until we reach `format!("error: {}", $x)`, at which point it is the 
792- /// oldest ancestor span that is both still local and shares the same [`SyntaxContext`] as the 
793- /// initial span. 
794- pub  fn  find_oldest_ancestor_in_same_ctxt ( self )  -> Span  { 
795-         let  mut  cur = self ; 
796-         while  cur. eq_ctxt ( self ) 
797-             && let  Some ( parent_callsite)  = cur. parent_callsite ( ) 
798-         { 
799-             cur = parent_callsite; 
797+ /// This method traverses the macro expansion ancestors until it finds a span 
798+ /// that originates from user-written code rather than any macro-generated code. 
799+ /// 
800+ /// This method is useful for reporting errors at the exact location users wrote code 
801+ /// and providing suggestions at directly editable locations. 
802+ /// 
803+ /// # See also 
804+ /// 
805+ /// - [`find_ancestor_not_from_extern_macro`]: Only filters out external macros, keeps local ones 
806+ /// - [`Span::from_expansion`]: Checks if a span comes from any macro expansion 
807+ pub  fn  find_ancestor_not_from_macro ( mut  self )  -> Option < Span >  { 
808+         while  self . from_expansion ( )  { 
809+             self  = self . parent_callsite ( ) ?; 
800810        } 
801-         cur 
811+         Some ( self ) 
802812    } 
803813
804814    /// Edition of the crate from which this span came. 
0 commit comments