fn annotate<F>(&mut self, id: NodeId, attrs: &[Attribute],
                   item_sp: Span, kind: AnnotationKind, visit_children: F)
        where F: FnOnce(&mut Self)
    {
        if self.tcx.features().staged_api {
            // This crate explicitly wants staged API.
            debug!("annotate(id = {:?}, attrs = {:?})", id, attrs);
            if let Some(..) = attr::find_deprecation(self.tcx.sess.diagnostic(), attrs, item_sp) {
                self.tcx.sess.span_err(item_sp, "`#[deprecated]` cannot be used in staged api, \
                                                 use `#[rustc_deprecated]` instead");
            }
            if let Some(mut stab) = attr::find_stability(self.tcx.sess.diagnostic(),
                                                         attrs, item_sp) {
                // Error if prohibited, or can't inherit anything from a container
                if kind == AnnotationKind::Prohibited ||
                   (kind == AnnotationKind::Container &&
                    stab.level.is_stable() &&
                    stab.rustc_depr.is_none()) {
                    self.tcx.sess.span_err(item_sp, "This stability annotation is useless");
                }

                debug!("annotate: found {:?}", stab);
                // If parent is deprecated and we're not, inherit this by merging
                // deprecated_since and its reason.
                if let Some(parent_stab) = self.parent_stab {
                    if parent_stab.rustc_depr.is_some() && stab.rustc_depr.is_none() {
                        stab.rustc_depr = parent_stab.rustc_depr.clone()
                    }
                }

                let stab = self.tcx.intern_stability(stab);

                // Check if deprecated_since < stable_since. If it is,
                // this is *almost surely* an accident.
                if let (&Some(attr::RustcDeprecation {since: dep_since, ..}),
                        &attr::Stable {since: stab_since}) = (&stab.rustc_depr, &stab.level) {
                    // Explicit version of iter::order::lt to handle parse errors properly
                    for (dep_v, stab_v) in
                            dep_since.as_str().split('.').zip(stab_since.as_str().split('.')) {
                        if let (Ok(dep_v), Ok(stab_v)) = (dep_v.parse::<u64>(), stab_v.parse()) {
                            match dep_v.cmp(&stab_v) {
                                Ordering::Less => {
                                    self.tcx.sess.span_err(item_sp, "An API can't be stabilized \
                                                                     after it is deprecated");
                                    break
                                }
                                Ordering::Equal => continue,
                                Ordering::Greater => break,
                            }
                        } else {
                            // Act like it isn't less because the question is now nonsensical,
                            // and this makes us not do anything else interesting.
                            self.tcx.sess.span_err(item_sp, "Invalid stability or deprecation \
                                                             version found");
                            break
                        }
                    }
                }

                let hir_id = self.tcx.hir.node_to_hir_id(id);
                self.index.stab_map.insert(hir_id, stab);

                let orig_parent_stab = replace(&mut self.parent_stab, Some(stab));
                visit_children(self);
                self.parent_stab = orig_parent_stab;
            } else {
                debug!("annotate: not found, parent = {:?}", self.parent_stab);
                if let Some(stab) = self.parent_stab {
                    if stab.level.is_unstable() {
                        let hir_id = self.tcx.hir.node_to_hir_id(id);
                        self.index.stab_map.insert(hir_id, stab);
                    }
                }
                visit_children(self);
            }
        } else {
            // Emit errors for non-staged-api crates.
            for attr in attrs {
                let tag = attr.name();
                if tag == "unstable" || tag == "stable" || tag == "rustc_deprecated" {
                    attr::mark_used(attr);
                    self.tcx.sess.span_err(attr.span(), "stability attributes may not be used \
                                                         outside of the standard library");
                }
            }

            // Propagate unstability.  This can happen even for non-staged-api crates in case
            // -Zforce-unstable-if-unmarked is set.
            if let Some(stab) = self.parent_stab {
                if stab.level.is_unstable() {
                    let hir_id = self.tcx.hir.node_to_hir_id(id);
                    self.index.stab_map.insert(hir_id, stab);
                }
            }

            if let Some(depr) = attr::find_deprecation(self.tcx.sess.diagnostic(), attrs, item_sp) {
                if kind == AnnotationKind::Prohibited {
                    self.tcx.sess.span_err(item_sp, "This deprecation annotation is useless");
                }

                // `Deprecation` is just two pointers, no need to intern it
                let hir_id = self.tcx.hir.node_to_hir_id(id);
                let depr_entry = DeprecationEntry::local(depr, hir_id);
                self.index.depr_map.insert(hir_id, depr_entry.clone());

                let orig_parent_depr = replace(&mut self.parent_depr,
                                               Some(depr_entry));
                visit_children(self);
                self.parent_depr = orig_parent_depr;
            } else if let Some(parent_depr) = self.parent_depr.clone() {
                let hir_id = self.tcx.hir.node_to_hir_id(id);
                self.index.depr_map.insert(hir_id, parent_depr);
                visit_children(self);
            } else {
                visit_children(self);
            }
        }
    }
// Determine the stability for a node based on its attributes and inherited
// stability. The stability is recorded in the index and used as the parent.
Determine the stability for a node based on its attributes and inherited
stability. The stability is recorded in the index and used as the parent.
Determine the stability for a node based on its attributes and inherited stability . The stability is recorded in the index and used as the parent .
fn annotate<F>(&mut self, id: NodeId, attrs: &[Attribute],
                   item_sp: Span, kind: AnnotationKind, visit_children: F)
        where F: FnOnce(&mut Self)
    {
        if self.tcx.features().staged_api {
            // This crate explicitly wants staged API.
            debug!("annotate(id = {:?}, attrs = {:?})", id, attrs);
            if let Some(..) = attr::find_deprecation(self.tcx.sess.diagnostic(), attrs, item_sp) {
                self.tcx.sess.span_err(item_sp, "`#[deprecated]` cannot be used in staged api, \
                                                 use `#[rustc_deprecated]` instead");
            }
            if let Some(mut stab) = attr::find_stability(self.tcx.sess.diagnostic(),
                                                         attrs, item_sp) {
                // Error if prohibited, or can't inherit anything from a container
                if kind == AnnotationKind::Prohibited ||
                   (kind == AnnotationKind::Container &&
                    stab.level.is_stable() &&
                    stab.rustc_depr.is_none()) {
                    self.tcx.sess.span_err(item_sp, "This stability annotation is useless");
                }
                debug!("annotate: found {:?}", stab);
                // If parent is deprecated and we're not, inherit this by merging
                // deprecated_since and its reason.
                if let Some(parent_stab) = self.parent_stab {
                    if parent_stab.rustc_depr.is_some() && stab.rustc_depr.is_none() {
                        stab.rustc_depr = parent_stab.rustc_depr.clone()
                    }
                }
                let stab = self.tcx.intern_stability(stab);
                // Check if deprecated_since < stable_since. If it is,
                // this is *almost surely* an accident.
                if let (&Some(attr::RustcDeprecation {since: dep_since, ..}),
                        &attr::Stable {since: stab_since}) = (&stab.rustc_depr, &stab.level) {
                    // Explicit version of iter::order::lt to handle parse errors properly
                    for (dep_v, stab_v) in
                            dep_since.as_str().split('.').zip(stab_since.as_str().split('.')) {
                        if let (Ok(dep_v), Ok(stab_v)) = (dep_v.parse::<u64>(), stab_v.parse()) {
                            match dep_v.cmp(&stab_v) {
                                Ordering::Less => {
                                    self.tcx.sess.span_err(item_sp, "An API can't be stabilized \
                                                                     after it is deprecated");
                                    break
                                }
                                Ordering::Equal => continue,
                                Ordering::Greater => break,
                            }
                        } else {
                            // Act like it isn't less because the question is now nonsensical,
                            // and this makes us not do anything else interesting.
                            self.tcx.sess.span_err(item_sp, "Invalid stability or deprecation \
                                                             version found");
                            break
                        }
                    }
                }
                let hir_id = self.tcx.hir.node_to_hir_id(id);
                self.index.stab_map.insert(hir_id, stab);
                let orig_parent_stab = replace(&mut self.parent_stab, Some(stab));
                visit_children(self);
                self.parent_stab = orig_parent_stab;
            } else {
                debug!("annotate: not found, parent = {:?}", self.parent_stab);
                if let Some(stab) = self.parent_stab {
                    if stab.level.is_unstable() {
                        let hir_id = self.tcx.hir.node_to_hir_id(id);
                        self.index.stab_map.insert(hir_id, stab);
                    }
                }
                visit_children(self);
            }
        } else {
            // Emit errors for non-staged-api crates.
            for attr in attrs {
                let tag = attr.name();
                if tag == "unstable" || tag == "stable" || tag == "rustc_deprecated" {
                    attr::mark_used(attr);
                    self.tcx.sess.span_err(attr.span(), "stability attributes may not be used \
                                                         outside of the standard library");
                }
            }
            // Propagate unstability.  This can happen even for non-staged-api crates in case
            // -Zforce-unstable-if-unmarked is set.
            if let Some(stab) = self.parent_stab {
                if stab.level.is_unstable() {
                    let hir_id = self.tcx.hir.node_to_hir_id(id);
                    self.index.stab_map.insert(hir_id, stab);
                }
            }
            if let Some(depr) = attr::find_deprecation(self.tcx.sess.diagnostic(), attrs, item_sp) {
                if kind == AnnotationKind::Prohibited {
                    self.tcx.sess.span_err(item_sp, "This deprecation annotation is useless");
                }
                // `Deprecation` is just two pointers, no need to intern it
                let hir_id = self.tcx.hir.node_to_hir_id(id);
                let depr_entry = DeprecationEntry::local(depr, hir_id);
                self.index.depr_map.insert(hir_id, depr_entry.clone());
                let orig_parent_depr = replace(&mut self.parent_depr,
                                               Some(depr_entry));
                visit_children(self);
                self.parent_depr = orig_parent_depr;
            } else if let Some(parent_depr) = self.parent_depr.clone() {
                let hir_id = self.tcx.hir.node_to_hir_id(id);
                self.index.depr_map.insert(hir_id, parent_depr);
                visit_children(self);
            } else {
                visit_children(self);
            }
        }
    }
fn annotate < F > ( & mut self , id : NodeId , attrs : & [ Attribute ] , item_sp : Span , kind : AnnotationKind , visit_children : F ) where F : FnOnce ( & mut Self ) { if self . tcx . features ( ) . staged_api { // This crate explicitly wants staged API. debug ! ( " " id attrs ) ; if let Some ( .. ) = attr :: find_deprecation ( self . tcx . sess . diagnostic ( ) , attrs , item_sp ) { self . tcx . sess . span_err ( item_sp , " \
 " ) ; } if let Some ( mut stab ) = attr :: find_stability ( self . tcx . sess . diagnostic ( ) , attrs , item_sp ) { // Error if prohibited, or can't inherit anything from a container if kind == AnnotationKind :: Prohibited || ( kind == AnnotationKind :: Container && stab . level . is_stable ( ) && stab . rustc_depr . is_none ( ) ) { self . tcx . sess . span_err ( item_sp , " " ) ; } debug ! ( " " stab ) ; // If parent is deprecated and we're not, inherit this by merging // deprecated_since and its reason. if let Some ( parent_stab ) = self . parent_stab { if parent_stab . rustc_depr . is_some ( ) && stab . rustc_depr . is_none ( ) { stab . rustc_depr = parent_stab . rustc_depr . clone ( ) } } let stab = self . tcx . intern_stability ( stab ) ; // Check if deprecated_since < stable_since. If it is, // this is *almost surely* an accident. if let ( & Some ( attr :: RustcDeprecation { since : dep_since , .. } ) , & attr :: Stable { since : stab_since } ) = ( & stab . rustc_depr , & stab . level ) { // Explicit version of iter::order::lt to handle parse errors properly for ( dep_v , stab_v ) in dep_since . as_str ( ) . split ( '.' ) . zip ( stab_since . as_str ( ) . split ( '.' ) ) { if let ( Ok ( dep_v ) , Ok ( stab_v ) ) = ( dep_v . parse :: < u64 > ( ) , stab_v . parse ( ) ) { match dep_v . cmp ( & stab_v ) { Ordering :: Less => { self . tcx . sess . span_err ( item_sp , " \
 " ) ; break } Ordering :: Equal => continue , Ordering :: Greater => break , } } else { // Act like it isn't less because the question is now nonsensical, // and this makes us not do anything else interesting. self . tcx . sess . span_err ( item_sp , " \
 " ) ; break } } } let hir_id = self . tcx . hir . node_to_hir_id ( id ) ; self . index . stab_map . insert ( hir_id , stab ) ; let orig_parent_stab = replace ( & mut self . parent_stab , Some ( stab ) ) ; visit_children ( self ) ; self . parent_stab = orig_parent_stab ; } else { debug ! ( " " self parent_stab ) ; if let Some ( stab ) = self . parent_stab { if stab . level . is_unstable ( ) { let hir_id = self . tcx . hir . node_to_hir_id ( id ) ; self . index . stab_map . insert ( hir_id , stab ) ; } } visit_children ( self ) ; } } else { // Emit errors for non-staged-api crates. for attr in attrs { let tag = attr . name ( ) ; if tag == " " || tag == " " || tag == " " { attr :: mark_used ( attr ) ; self . tcx . sess . span_err ( attr . span ( ) , " \
 " ) ; } } // Propagate unstability.  This can happen even for non-staged-api crates in case // -Zforce-unstable-if-unmarked is set. if let Some ( stab ) = self . parent_stab { if stab . level . is_unstable ( ) { let hir_id = self . tcx . hir . node_to_hir_id ( id ) ; self . index . stab_map . insert ( hir_id , stab ) ; } } if let Some ( depr ) = attr :: find_deprecation ( self . tcx . sess . diagnostic ( ) , attrs , item_sp ) { if kind == AnnotationKind :: Prohibited { self . tcx . sess . span_err ( item_sp , " " ) ; } // `Deprecation` is just two pointers, no need to intern it let hir_id = self . tcx . hir . node_to_hir_id ( id ) ; let depr_entry = DeprecationEntry :: local ( depr , hir_id ) ; self . index . depr_map . insert ( hir_id , depr_entry . clone ( ) ) ; let orig_parent_depr = replace ( & mut self . parent_depr , Some ( depr_entry ) ) ; visit_children ( self ) ; self . parent_depr = orig_parent_depr ; } else if let Some ( parent_depr ) = self . parent_depr . clone ( ) { let hir_id = self . tcx . hir . node_to_hir_id ( id ) ; self . index . depr_map . insert ( hir_id , parent_depr ) ; visit_children ( self ) ; } else { visit_children ( self ) ; } } }
Determine the stability for a node based on its attributes and inherited
stability.
Determine the stability for a node based on its attributes and inherited stability .
&mut self
id
NodeId
attrs
&[Attribute]
item_sp
Span
kind
AnnotationKind
visit_children
F
&mut self
id
NodeId
attrs
&[Attribute]
item_sp
Span
kind
AnnotationKind
visit_children
F