/// Attempts to highlight the specific part of a type annotation
/// that contains the anonymous reference we want to give a name
/// to. For example, we might produce an annotation like this:
///
/// ```
///  | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
///  |                - let's call the lifetime of this reference `'1`
/// ```
///
/// the way this works is that we match up `argument_ty`, which is
/// a `Ty<'tcx>` (the internal form of the type) with
/// `argument_hir_ty`, a `hir::Ty` (the syntax of the type
/// annotation). We are descending through the types stepwise,
/// looking in to find the region `needle_fr` in the internal
/// type.  Once we find that, we can use the span of the `hir::Ty`
/// to add the highlight.
///
/// This is a somewhat imperfect process, so long the way we also
/// keep track of the **closest** type we've found. If we fail to
/// find the exact `&` or `'_` to highlight, then we may fall back
/// to highlighting that closest type instead.
Attempts to highlight the specific part of a type annotation
that contains the anonymous reference we want to give a name
to. For example, we might produce an annotation like this.





This is a somewhat imperfect process, so long the way we also
keep track of the **closest** type we've found. If we fail to
find the exact `&` or `'_` to highlight, then we may fall back
to highlighting that closest type instead.
Attempts to highlight the specific part of a type annotation that contains the anonymous reference we want to give a name to . For example we might produce an annotation like this . This is a somewhat imperfect process so long the way we also keep track of the ** closest ** type we ' ve found . If we fail to find the exact ` & ` or ` ' _ ` to highlight then we may fall back to highlighting that closest type instead .
fn give_name_if_we_can_match_hir_ty(
        &self,
        tcx: TyCtxt<'_, '_, 'tcx>,
        needle_fr: RegionVid,
        argument_ty: Ty<'tcx>,
        argument_hir_ty: &hir::Ty,
        counter: &mut usize,
        diag: &mut DiagnosticBuilder<'_>,
    ) -> Option<InternedString> {
        let search_stack: &mut Vec<(Ty<'tcx>, &hir::Ty)> = &mut Vec::new();
        search_stack.push((argument_ty, argument_hir_ty));
        while let Some((ty, hir_ty)) = search_stack.pop() {
            match (&ty.sty, &hir_ty.node) {
                // Check if the `argument_ty` is `&'X ..` where `'X`
                // is the region we are looking for -- if so, and we have a `&T`
                // on the RHS, then we want to highlight the `&` like so:
                //
                //     &
                //     - let's call the lifetime of this reference `'1`
                (
                    ty::TyRef(region, referent_ty, _),
                    hir::TyKind::Rptr(_lifetime, referent_hir_ty),
                ) => {
                    if region.to_region_vid() == needle_fr {
                        let region_name = self.synthesize_region_name(counter);
                        // Just grab the first character, the `&`.
                        let source_map = tcx.sess.source_map();
                        let ampersand_span = source_map.start_point(hir_ty.span);
                        diag.span_label(
                            ampersand_span,
                            format!(
                                "let's call the lifetime of this reference `{}`",
                                region_name
                            ),
                        );
                        return Some(region_name);
                    }
                    // Otherwise, let's descend into the referent types.
                    search_stack.push((referent_ty, &referent_hir_ty.ty));
                }
                // Match up something like `Foo<'1>`
                (
                    ty::TyAdt(_adt_def, substs),
                    hir::TyKind::Path(hir::QPath::Resolved(None, path)),
                ) => {
                    if let Some(last_segment) = path.segments.last() {
                        if let Some(name) = self.match_adt_and_segment(
                            substs,
                            needle_fr,
                            last_segment,
                            counter,
                            diag,
                            search_stack,
                        ) {
                            return Some(name);
                        }
                    }
                }
                // The following cases don't have lifetimes, so we
                // just worry about trying to match up the rustc type
                // with the HIR types:
                (ty::TyTuple(elem_tys), hir::TyKind::Tup(elem_hir_tys)) => {
                    search_stack.extend(elem_tys.iter().cloned().zip(elem_hir_tys));
                }
                (ty::TySlice(elem_ty), hir::TyKind::Slice(elem_hir_ty))
                | (ty::TyArray(elem_ty, _), hir::TyKind::Array(elem_hir_ty, _)) => {
                    search_stack.push((elem_ty, elem_hir_ty));
                }
                (ty::TyRawPtr(mut_ty), hir::TyKind::Ptr(mut_hir_ty)) => {
                    search_stack.push((mut_ty.ty, &mut_hir_ty.ty));
                }
                _ => {
                    // FIXME there are other cases that we could trace
                }
            }
        }
        return None;
    }
fn give_name_if_we_can_match_hir_ty ( & self , tcx : TyCtxt < ' _ , ' _ , ' tcx > , needle_fr : RegionVid , argument_ty : Ty < ' tcx > , argument_hir_ty : & hir :: Ty , counter : & mut usize , diag : & mut DiagnosticBuilder < ' _ > , ) -> Option < InternedString > { let search_stack : & mut Vec < ( Ty < ' tcx > , & hir :: Ty ) > = & mut Vec :: new ( ) ; search_stack . push ( ( argument_ty , argument_hir_ty ) ) ; while let Some ( ( ty , hir_ty ) ) = search_stack . pop ( ) { match ( & ty . sty , & hir_ty . node ) { // Check if the `argument_ty` is `&'X ..` where `'X` // is the region we are looking for -- if so, and we have a `&T` // on the RHS, then we want to highlight the `&` like so: // //     & //     - let's call the lifetime of this reference `'1` ( ty :: TyRef ( region , referent_ty , _ ) , hir :: TyKind :: Rptr ( _lifetime , referent_hir_ty ) , ) => { if region . to_region_vid ( ) == needle_fr { let region_name = self . synthesize_region_name ( counter ) ; // Just grab the first character, the `&`. let source_map = tcx . sess . source_map ( ) ; let ampersand_span = source_map . start_point ( hir_ty . span ) ; diag . span_label ( ampersand_span , format ! ( " " region_name ) , ) ; return Some ( region_name ) ; } // Otherwise, let's descend into the referent types. search_stack . push ( ( referent_ty , & referent_hir_ty . ty ) ) ; } // Match up something like `Foo<'1>` ( ty :: TyAdt ( _adt_def , substs ) , hir :: TyKind :: Path ( hir :: QPath :: Resolved ( None , path ) ) , ) => { if let Some ( last_segment ) = path . segments . last ( ) { if let Some ( name ) = self . match_adt_and_segment ( substs , needle_fr , last_segment , counter , diag , search_stack , ) { return Some ( name ) ; } } } // The following cases don't have lifetimes, so we // just worry about trying to match up the rustc type // with the HIR types: ( ty :: TyTuple ( elem_tys ) , hir :: TyKind :: Tup ( elem_hir_tys ) ) => { search_stack . extend ( elem_tys . iter ( ) . cloned ( ) . zip ( elem_hir_tys ) ) ; } ( ty :: TySlice ( elem_ty ) , hir :: TyKind :: Slice ( elem_hir_ty ) ) | ( ty :: TyArray ( elem_ty , _ ) , hir :: TyKind :: Array ( elem_hir_ty , _ ) ) => { search_stack . push ( ( elem_ty , elem_hir_ty ) ) ; } ( ty :: TyRawPtr ( mut_ty ) , hir :: TyKind :: Ptr ( mut_hir_ty ) ) => { search_stack . push ( ( mut_ty . ty , & mut_hir_ty . ty ) ) ; } _ => { // FIXME there are other cases that we could trace } } } return None ; }
Attempts to highlight the specific part of a type annotation
that contains the anonymous reference we want to give a name
to.
Attempts to highlight the specific part of a type annotation that contains the anonymous reference we want to give a name to .
&self
tcx
TyCtxt<'_, '_, 'tcx>
needle_fr
RegionVid
argument_ty
Ty<'tcx>
argument_hir_ty
&hir::Ty
counter
&mut usize
diag
&mut DiagnosticBuilder<'_>