1
Fork 0

Add documentation

This commit is contained in:
Avi Dessauer 2020-07-05 19:02:30 -04:00 committed by Jacob Hughes
parent 3947591ee8
commit 19e90843a4
3 changed files with 90 additions and 36 deletions

View file

@ -395,7 +395,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// This function will also check if the item is deprecated. /// This function will also check if the item is deprecated.
/// If so, and `id` is not `None`, a deprecated lint attached to `id` will be emitted. /// If so, and `id` is not `None`, a deprecated lint attached to `id` will be emitted.
pub fn check_stability(self, def_id: DefId, id: Option<HirId>, span: Span) { pub fn check_stability(self, def_id: DefId, id: Option<HirId>, span: Span) {
self.check_stability_internal(def_id, id, span, |span, def_id| { self.check_optional_stability(def_id, id, span, |span, def_id| {
// The API could be uncallable for other reasons, for example when a private module // The API could be uncallable for other reasons, for example when a private module
// was referenced. // was referenced.
self.sess.delay_span_bug(span, &format!("encountered unmarked API: {:?}", def_id)); self.sess.delay_span_bug(span, &format!("encountered unmarked API: {:?}", def_id));
@ -409,7 +409,10 @@ impl<'tcx> TyCtxt<'tcx> {
/// ///
/// This function will also check if the item is deprecated. /// This function will also check if the item is deprecated.
/// If so, and `id` is not `None`, a deprecated lint attached to `id` will be emitted. /// If so, and `id` is not `None`, a deprecated lint attached to `id` will be emitted.
pub fn check_stability_internal( ///
/// The `unmarked` closure is called definitions without a stability annotation.
/// This is needed for generic parameters, since they may not be marked when used in a staged_api crate.
pub fn check_optional_stability(
self, self,
def_id: DefId, def_id: DefId,
id: Option<HirId>, id: Option<HirId>,

View file

@ -37,6 +37,20 @@ enum AnnotationKind {
Container, Container,
} }
/// Inheriting deprecations Nested items causes duplicate warnings.
/// Inheriting the deprecation of `Foo<T>` onto the parameter `T`, would cause a duplicate warnings.
#[derive(PartialEq, Copy, Clone)]
enum InheritDeprecation {
Yes,
No,
}
impl InheritDeprecation {
fn yes(&self) -> bool {
*self == InheritDeprecation::Yes
}
}
// A private tree-walker for producing an Index. // A private tree-walker for producing an Index.
struct Annotator<'a, 'tcx> { struct Annotator<'a, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
@ -56,7 +70,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
attrs: &[Attribute], attrs: &[Attribute],
item_sp: Span, item_sp: Span,
kind: AnnotationKind, kind: AnnotationKind,
inherit_deprecation: bool, inherit_deprecation: InheritDeprecation,
visit_children: F, visit_children: F,
) where ) where
F: FnOnce(&mut Self), F: FnOnce(&mut Self),
@ -81,7 +95,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
let depr_entry = DeprecationEntry::local(depr.clone(), hir_id); let depr_entry = DeprecationEntry::local(depr.clone(), hir_id);
self.index.depr_map.insert(hir_id, depr_entry); self.index.depr_map.insert(hir_id, depr_entry);
} else if let Some(parent_depr) = self.parent_depr.clone() { } else if let Some(parent_depr) = self.parent_depr.clone() {
if inherit_deprecation { if inherit_deprecation.yes() {
is_deprecated = true; is_deprecated = true;
info!("tagging child {:?} as deprecated from parent", hir_id); info!("tagging child {:?} as deprecated from parent", hir_id);
self.index.depr_map.insert(hir_id, parent_depr); self.index.depr_map.insert(hir_id, parent_depr);
@ -189,7 +203,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
if stab.is_none() { if stab.is_none() {
debug!("annotate: stab not found, parent = {:?}", self.parent_stab); debug!("annotate: stab not found, parent = {:?}", self.parent_stab);
if let Some(stab) = self.parent_stab { if let Some(stab) = self.parent_stab {
if inherit_deprecation && stab.level.is_unstable() { if inherit_deprecation.yes() && stab.level.is_unstable() {
self.index.stab_map.insert(hir_id, stab); self.index.stab_map.insert(hir_id, stab);
} }
} }
@ -240,7 +254,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
} }
// returns true if an error occurred, used to suppress some spurious errors // returns true if an error occurred, used to suppress some spurious errors
fn forbid_staged_api_attrs(&mut self, hir_id: HirId, attrs: &[Attribute], inherit_deprecation: bool) -> bool { fn forbid_staged_api_attrs(&mut self, hir_id: HirId, attrs: &[Attribute], inherit_deprecation: InheritDeprecation) -> bool {
// Emit errors for non-staged-api crates. // Emit errors for non-staged-api crates.
let unstable_attrs = [ let unstable_attrs = [
sym::unstable, sym::unstable,
@ -268,7 +282,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
// Propagate unstability. This can happen even for non-staged-api crates in case // Propagate unstability. This can happen even for non-staged-api crates in case
// -Zforce-unstable-if-unmarked is set. // -Zforce-unstable-if-unmarked is set.
if let Some(stab) = self.parent_stab { if let Some(stab) = self.parent_stab {
if inherit_deprecation && stab.level.is_unstable() { if inherit_deprecation.yes() && stab.level.is_unstable() {
self.index.stab_map.insert(hir_id, stab); self.index.stab_map.insert(hir_id, stab);
} }
} }
@ -309,7 +323,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
&i.attrs, &i.attrs,
i.span, i.span,
AnnotationKind::Required, AnnotationKind::Required,
true, InheritDeprecation::Yes,
|_| {}, |_| {},
) )
} }
@ -317,55 +331,92 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
_ => {} _ => {}
} }
self.annotate(i.hir_id, &i.attrs, i.span, kind, true, |v| intravisit::walk_item(v, i)); self.annotate(i.hir_id, &i.attrs, i.span, kind, InheritDeprecation::Yes, |v| {
intravisit::walk_item(v, i)
});
self.in_trait_impl = orig_in_trait_impl; self.in_trait_impl = orig_in_trait_impl;
} }
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem<'tcx>) { fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem<'tcx>) {
self.annotate(ti.hir_id, &ti.attrs, ti.span, AnnotationKind::Required, true, |v| { self.annotate(
ti.hir_id,
&ti.attrs,
ti.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
|v| {
intravisit::walk_trait_item(v, ti); intravisit::walk_trait_item(v, ti);
}); },
);
} }
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) { fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) {
let kind = let kind =
if self.in_trait_impl { AnnotationKind::Prohibited } else { AnnotationKind::Required }; if self.in_trait_impl { AnnotationKind::Prohibited } else { AnnotationKind::Required };
self.annotate(ii.hir_id, &ii.attrs, ii.span, kind, true, |v| { self.annotate(ii.hir_id, &ii.attrs, ii.span, kind, InheritDeprecation::Yes, |v| {
intravisit::walk_impl_item(v, ii); intravisit::walk_impl_item(v, ii);
}); });
} }
fn visit_variant(&mut self, var: &'tcx Variant<'tcx>, g: &'tcx Generics<'tcx>, item_id: HirId) { fn visit_variant(&mut self, var: &'tcx Variant<'tcx>, g: &'tcx Generics<'tcx>, item_id: HirId) {
self.annotate(var.id, &var.attrs, var.span, AnnotationKind::Required, true, |v| { self.annotate(
var.id,
&var.attrs,
var.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
|v| {
if let Some(ctor_hir_id) = var.data.ctor_hir_id() { if let Some(ctor_hir_id) = var.data.ctor_hir_id() {
v.annotate( v.annotate(
ctor_hir_id, ctor_hir_id,
&var.attrs, &var.attrs,
var.span, var.span,
AnnotationKind::Required, AnnotationKind::Required,
true, InheritDeprecation::Yes,
|_| {}, |_| {},
); );
} }
intravisit::walk_variant(v, var, g, item_id) intravisit::walk_variant(v, var, g, item_id)
}) },
)
} }
fn visit_struct_field(&mut self, s: &'tcx StructField<'tcx>) { fn visit_struct_field(&mut self, s: &'tcx StructField<'tcx>) {
self.annotate(s.hir_id, &s.attrs, s.span, AnnotationKind::Required, true, |v| { self.annotate(
s.hir_id,
&s.attrs,
s.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
|v| {
intravisit::walk_struct_field(v, s); intravisit::walk_struct_field(v, s);
}); },
);
} }
fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem<'tcx>) { fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem<'tcx>) {
self.annotate(i.hir_id, &i.attrs, i.span, AnnotationKind::Required, true, |v| { self.annotate(
i.hir_id,
&i.attrs,
i.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
|v| {
intravisit::walk_foreign_item(v, i); intravisit::walk_foreign_item(v, i);
}); },
);
} }
fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) { fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) {
self.annotate(md.hir_id, &md.attrs, md.span, AnnotationKind::Required, true, |_| {}); self.annotate(
md.hir_id,
&md.attrs,
md.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
|_| {},
);
} }
fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) { fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
@ -377,7 +428,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
_ => AnnotationKind::Prohibited, _ => AnnotationKind::Prohibited,
}; };
self.annotate(p.hir_id, &p.attrs, p.span, kind, false, |v| { self.annotate(p.hir_id, &p.attrs, p.span, kind, InheritDeprecation::No, |v| {
intravisit::walk_generic_param(v, p); intravisit::walk_generic_param(v, p);
}); });
} }
@ -519,7 +570,7 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
&krate.item.attrs, &krate.item.attrs,
krate.item.span, krate.item.span,
AnnotationKind::Required, AnnotationKind::Required,
true, InheritDeprecation::Yes,
|v| intravisit::walk_crate(v, krate), |v| intravisit::walk_crate(v, krate),
); );
} }

View file

@ -362,7 +362,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
} }
(GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => { (GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => {
if *has_default { if *has_default {
tcx.check_stability_internal( tcx.check_optional_stability(
param.def_id, param.def_id,
Some(arg.id()), Some(arg.id()),
arg.span(), arg.span(),