]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_privacy/src/lib.rs
Auto merge of #98569 - nnethercote:finalize_resolutions_id, r=cjgillot
[rust.git] / compiler / rustc_privacy / src / lib.rs
1 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
2 #![feature(associated_type_defaults)]
3 #![feature(control_flow_enum)]
4 #![feature(rustc_private)]
5 #![feature(try_blocks)]
6 #![recursion_limit = "256"]
7 #![allow(rustc::potential_query_instability)]
8 #![cfg_attr(not(bootstrap), deny(rustc::untranslatable_diagnostic))]
9 #![cfg_attr(not(bootstrap), deny(rustc::diagnostic_outside_of_impl))]
10
11 mod errors;
12
13 use rustc_ast::MacroDef;
14 use rustc_attr as attr;
15 use rustc_data_structures::fx::FxHashSet;
16 use rustc_data_structures::intern::Interned;
17 use rustc_hir as hir;
18 use rustc_hir::def::{DefKind, Res};
19 use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID};
20 use rustc_hir::intravisit::{self, Visitor};
21 use rustc_hir::{AssocItemKind, HirIdSet, ItemId, Node, PatKind};
22 use rustc_middle::bug;
23 use rustc_middle::hir::nested_filter;
24 use rustc_middle::middle::privacy::{AccessLevel, AccessLevels};
25 use rustc_middle::span_bug;
26 use rustc_middle::thir::abstract_const::Node as ACNode;
27 use rustc_middle::ty::query::Providers;
28 use rustc_middle::ty::subst::InternalSubsts;
29 use rustc_middle::ty::{self, Const, DefIdTree, GenericParamDefKind};
30 use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitor};
31 use rustc_session::lint;
32 use rustc_span::hygiene::Transparency;
33 use rustc_span::symbol::{kw, Ident};
34 use rustc_span::Span;
35 use rustc_trait_selection::traits::const_evaluatable::{self, AbstractConst};
36
37 use std::marker::PhantomData;
38 use std::ops::ControlFlow;
39 use std::{cmp, fmt, mem};
40
41 use errors::{
42     FieldIsPrivate, FieldIsPrivateLabel, InPublicInterface, InPublicInterfaceTraits, ItemIsPrivate,
43     UnnamedItemIsPrivate,
44 };
45
46 ////////////////////////////////////////////////////////////////////////////////
47 /// Generic infrastructure used to implement specific visitors below.
48 ////////////////////////////////////////////////////////////////////////////////
49
50 /// Implemented to visit all `DefId`s in a type.
51 /// Visiting `DefId`s is useful because visibilities and reachabilities are attached to them.
52 /// The idea is to visit "all components of a type", as documented in
53 /// <https://github.com/rust-lang/rfcs/blob/master/text/2145-type-privacy.md#how-to-determine-visibility-of-a-type>.
54 /// The default type visitor (`TypeVisitor`) does most of the job, but it has some shortcomings.
55 /// First, it doesn't have overridable `fn visit_trait_ref`, so we have to catch trait `DefId`s
56 /// manually. Second, it doesn't visit some type components like signatures of fn types, or traits
57 /// in `impl Trait`, see individual comments in `DefIdVisitorSkeleton::visit_ty`.
58 trait DefIdVisitor<'tcx> {
59     type BreakTy = ();
60
61     fn tcx(&self) -> TyCtxt<'tcx>;
62     fn shallow(&self) -> bool {
63         false
64     }
65     fn skip_assoc_tys(&self) -> bool {
66         false
67     }
68     fn visit_def_id(
69         &mut self,
70         def_id: DefId,
71         kind: &str,
72         descr: &dyn fmt::Display,
73     ) -> ControlFlow<Self::BreakTy>;
74
75     /// Not overridden, but used to actually visit types and traits.
76     fn skeleton(&mut self) -> DefIdVisitorSkeleton<'_, 'tcx, Self> {
77         DefIdVisitorSkeleton {
78             def_id_visitor: self,
79             visited_opaque_tys: Default::default(),
80             dummy: Default::default(),
81         }
82     }
83     fn visit(&mut self, ty_fragment: impl TypeFoldable<'tcx>) -> ControlFlow<Self::BreakTy> {
84         ty_fragment.visit_with(&mut self.skeleton())
85     }
86     fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow<Self::BreakTy> {
87         self.skeleton().visit_trait(trait_ref)
88     }
89     fn visit_projection_ty(
90         &mut self,
91         projection: ty::ProjectionTy<'tcx>,
92     ) -> ControlFlow<Self::BreakTy> {
93         self.skeleton().visit_projection_ty(projection)
94     }
95     fn visit_predicates(
96         &mut self,
97         predicates: ty::GenericPredicates<'tcx>,
98     ) -> ControlFlow<Self::BreakTy> {
99         self.skeleton().visit_predicates(predicates)
100     }
101 }
102
103 struct DefIdVisitorSkeleton<'v, 'tcx, V: ?Sized> {
104     def_id_visitor: &'v mut V,
105     visited_opaque_tys: FxHashSet<DefId>,
106     dummy: PhantomData<TyCtxt<'tcx>>,
107 }
108
109 impl<'tcx, V> DefIdVisitorSkeleton<'_, 'tcx, V>
110 where
111     V: DefIdVisitor<'tcx> + ?Sized,
112 {
113     fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow<V::BreakTy> {
114         let TraitRef { def_id, substs } = trait_ref;
115         self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref.print_only_trait_path())?;
116         if self.def_id_visitor.shallow() { ControlFlow::CONTINUE } else { substs.visit_with(self) }
117     }
118
119     fn visit_projection_ty(
120         &mut self,
121         projection: ty::ProjectionTy<'tcx>,
122     ) -> ControlFlow<V::BreakTy> {
123         let (trait_ref, assoc_substs) =
124             projection.trait_ref_and_own_substs(self.def_id_visitor.tcx());
125         self.visit_trait(trait_ref)?;
126         if self.def_id_visitor.shallow() {
127             ControlFlow::CONTINUE
128         } else {
129             assoc_substs.iter().try_for_each(|subst| subst.visit_with(self))
130         }
131     }
132
133     fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<V::BreakTy> {
134         match predicate.kind().skip_binder() {
135             ty::PredicateKind::Trait(ty::TraitPredicate {
136                 trait_ref,
137                 constness: _,
138                 polarity: _,
139             }) => self.visit_trait(trait_ref),
140             ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
141                 term.visit_with(self)?;
142                 self.visit_projection_ty(projection_ty)
143             }
144             ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty, _region)) => {
145                 ty.visit_with(self)
146             }
147             ty::PredicateKind::RegionOutlives(..) => ControlFlow::CONTINUE,
148             ty::PredicateKind::ConstEvaluatable(uv)
149                 if self.def_id_visitor.tcx().features().generic_const_exprs =>
150             {
151                 let tcx = self.def_id_visitor.tcx();
152                 if let Ok(Some(ct)) = AbstractConst::new(tcx, uv) {
153                     self.visit_abstract_const_expr(tcx, ct)?;
154                 }
155                 ControlFlow::CONTINUE
156             }
157             ty::PredicateKind::WellFormed(arg) => arg.visit_with(self),
158             _ => bug!("unexpected predicate: {:?}", predicate),
159         }
160     }
161
162     fn visit_abstract_const_expr(
163         &mut self,
164         tcx: TyCtxt<'tcx>,
165         ct: AbstractConst<'tcx>,
166     ) -> ControlFlow<V::BreakTy> {
167         const_evaluatable::walk_abstract_const(tcx, ct, |node| match node.root(tcx) {
168             ACNode::Leaf(leaf) => self.visit_const(leaf),
169             ACNode::Cast(_, _, ty) => self.visit_ty(ty),
170             ACNode::Binop(..) | ACNode::UnaryOp(..) | ACNode::FunctionCall(_, _) => {
171                 ControlFlow::CONTINUE
172             }
173         })
174     }
175
176     fn visit_predicates(
177         &mut self,
178         predicates: ty::GenericPredicates<'tcx>,
179     ) -> ControlFlow<V::BreakTy> {
180         let ty::GenericPredicates { parent: _, predicates } = predicates;
181         predicates.iter().try_for_each(|&(predicate, _span)| self.visit_predicate(predicate))
182     }
183 }
184
185 impl<'tcx, V> TypeVisitor<'tcx> for DefIdVisitorSkeleton<'_, 'tcx, V>
186 where
187     V: DefIdVisitor<'tcx> + ?Sized,
188 {
189     type BreakTy = V::BreakTy;
190
191     fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<V::BreakTy> {
192         let tcx = self.def_id_visitor.tcx();
193         // InternalSubsts are not visited here because they are visited below
194         // in `super_visit_with`.
195         match *ty.kind() {
196             ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), ..)
197             | ty::Foreign(def_id)
198             | ty::FnDef(def_id, ..)
199             | ty::Closure(def_id, ..)
200             | ty::Generator(def_id, ..) => {
201                 self.def_id_visitor.visit_def_id(def_id, "type", &ty)?;
202                 if self.def_id_visitor.shallow() {
203                     return ControlFlow::CONTINUE;
204                 }
205                 // Default type visitor doesn't visit signatures of fn types.
206                 // Something like `fn() -> Priv {my_func}` is considered a private type even if
207                 // `my_func` is public, so we need to visit signatures.
208                 if let ty::FnDef(..) = ty.kind() {
209                     tcx.fn_sig(def_id).visit_with(self)?;
210                 }
211                 // Inherent static methods don't have self type in substs.
212                 // Something like `fn() {my_method}` type of the method
213                 // `impl Pub<Priv> { pub fn my_method() {} }` is considered a private type,
214                 // so we need to visit the self type additionally.
215                 if let Some(assoc_item) = tcx.opt_associated_item(def_id) {
216                     if let ty::ImplContainer(impl_def_id) = assoc_item.container {
217                         tcx.type_of(impl_def_id).visit_with(self)?;
218                     }
219                 }
220             }
221             ty::Projection(proj) => {
222                 if self.def_id_visitor.skip_assoc_tys() {
223                     // Visitors searching for minimal visibility/reachability want to
224                     // conservatively approximate associated types like `<Type as Trait>::Alias`
225                     // as visible/reachable even if both `Type` and `Trait` are private.
226                     // Ideally, associated types should be substituted in the same way as
227                     // free type aliases, but this isn't done yet.
228                     return ControlFlow::CONTINUE;
229                 }
230                 // This will also visit substs if necessary, so we don't need to recurse.
231                 return self.visit_projection_ty(proj);
232             }
233             ty::Dynamic(predicates, ..) => {
234                 // All traits in the list are considered the "primary" part of the type
235                 // and are visited by shallow visitors.
236                 for predicate in predicates {
237                     let trait_ref = match predicate.skip_binder() {
238                         ty::ExistentialPredicate::Trait(trait_ref) => trait_ref,
239                         ty::ExistentialPredicate::Projection(proj) => proj.trait_ref(tcx),
240                         ty::ExistentialPredicate::AutoTrait(def_id) => {
241                             ty::ExistentialTraitRef { def_id, substs: InternalSubsts::empty() }
242                         }
243                     };
244                     let ty::ExistentialTraitRef { def_id, substs: _ } = trait_ref;
245                     self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref)?;
246                 }
247             }
248             ty::Opaque(def_id, ..) => {
249                 // Skip repeated `Opaque`s to avoid infinite recursion.
250                 if self.visited_opaque_tys.insert(def_id) {
251                     // The intent is to treat `impl Trait1 + Trait2` identically to
252                     // `dyn Trait1 + Trait2`. Therefore we ignore def-id of the opaque type itself
253                     // (it either has no visibility, or its visibility is insignificant, like
254                     // visibilities of type aliases) and recurse into bounds instead to go
255                     // through the trait list (default type visitor doesn't visit those traits).
256                     // All traits in the list are considered the "primary" part of the type
257                     // and are visited by shallow visitors.
258                     self.visit_predicates(ty::GenericPredicates {
259                         parent: None,
260                         predicates: tcx.explicit_item_bounds(def_id),
261                     })?;
262                 }
263             }
264             // These types don't have their own def-ids (but may have subcomponents
265             // with def-ids that should be visited recursively).
266             ty::Bool
267             | ty::Char
268             | ty::Int(..)
269             | ty::Uint(..)
270             | ty::Float(..)
271             | ty::Str
272             | ty::Never
273             | ty::Array(..)
274             | ty::Slice(..)
275             | ty::Tuple(..)
276             | ty::RawPtr(..)
277             | ty::Ref(..)
278             | ty::FnPtr(..)
279             | ty::Param(..)
280             | ty::Error(_)
281             | ty::GeneratorWitness(..) => {}
282             ty::Bound(..) | ty::Placeholder(..) | ty::Infer(..) => {
283                 bug!("unexpected type: {:?}", ty)
284             }
285         }
286
287         if self.def_id_visitor.shallow() {
288             ControlFlow::CONTINUE
289         } else {
290             ty.super_visit_with(self)
291         }
292     }
293
294     fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> {
295         self.visit_ty(c.ty())?;
296         let tcx = self.def_id_visitor.tcx();
297         if let Ok(Some(ct)) = AbstractConst::from_const(tcx, c) {
298             self.visit_abstract_const_expr(tcx, ct)?;
299         }
300         ControlFlow::CONTINUE
301     }
302 }
303
304 fn min(vis1: ty::Visibility, vis2: ty::Visibility, tcx: TyCtxt<'_>) -> ty::Visibility {
305     if vis1.is_at_least(vis2, tcx) { vis2 } else { vis1 }
306 }
307
308 ////////////////////////////////////////////////////////////////////////////////
309 /// Visitor used to determine impl visibility and reachability.
310 ////////////////////////////////////////////////////////////////////////////////
311
312 struct FindMin<'a, 'tcx, VL: VisibilityLike> {
313     tcx: TyCtxt<'tcx>,
314     access_levels: &'a AccessLevels,
315     min: VL,
316 }
317
318 impl<'a, 'tcx, VL: VisibilityLike> DefIdVisitor<'tcx> for FindMin<'a, 'tcx, VL> {
319     fn tcx(&self) -> TyCtxt<'tcx> {
320         self.tcx
321     }
322     fn shallow(&self) -> bool {
323         VL::SHALLOW
324     }
325     fn skip_assoc_tys(&self) -> bool {
326         true
327     }
328     fn visit_def_id(
329         &mut self,
330         def_id: DefId,
331         _kind: &str,
332         _descr: &dyn fmt::Display,
333     ) -> ControlFlow<Self::BreakTy> {
334         self.min = VL::new_min(self, def_id);
335         ControlFlow::CONTINUE
336     }
337 }
338
339 trait VisibilityLike: Sized {
340     const MAX: Self;
341     const SHALLOW: bool = false;
342     fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self;
343
344     // Returns an over-approximation (`skip_assoc_tys` = true) of visibility due to
345     // associated types for which we can't determine visibility precisely.
346     fn of_impl(def_id: LocalDefId, tcx: TyCtxt<'_>, access_levels: &AccessLevels) -> Self {
347         let mut find = FindMin { tcx, access_levels, min: Self::MAX };
348         find.visit(tcx.type_of(def_id));
349         if let Some(trait_ref) = tcx.impl_trait_ref(def_id) {
350             find.visit_trait(trait_ref);
351         }
352         find.min
353     }
354 }
355 impl VisibilityLike for ty::Visibility {
356     const MAX: Self = ty::Visibility::Public;
357     fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self {
358         min(find.tcx.visibility(def_id), find.min, find.tcx)
359     }
360 }
361 impl VisibilityLike for Option<AccessLevel> {
362     const MAX: Self = Some(AccessLevel::Public);
363     // Type inference is very smart sometimes.
364     // It can make an impl reachable even some components of its type or trait are unreachable.
365     // E.g. methods of `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
366     // can be usable from other crates (#57264). So we skip substs when calculating reachability
367     // and consider an impl reachable if its "shallow" type and trait are reachable.
368     //
369     // The assumption we make here is that type-inference won't let you use an impl without knowing
370     // both "shallow" version of its self type and "shallow" version of its trait if it exists
371     // (which require reaching the `DefId`s in them).
372     const SHALLOW: bool = true;
373     fn new_min(find: &FindMin<'_, '_, Self>, def_id: DefId) -> Self {
374         cmp::min(
375             if let Some(def_id) = def_id.as_local() {
376                 find.access_levels.map.get(&def_id).copied()
377             } else {
378                 Self::MAX
379             },
380             find.min,
381         )
382     }
383 }
384
385 ////////////////////////////////////////////////////////////////////////////////
386 /// The embargo visitor, used to determine the exports of the AST.
387 ////////////////////////////////////////////////////////////////////////////////
388
389 struct EmbargoVisitor<'tcx> {
390     tcx: TyCtxt<'tcx>,
391
392     /// Accessibility levels for reachable nodes.
393     access_levels: AccessLevels,
394     /// A set of pairs corresponding to modules, where the first module is
395     /// reachable via a macro that's defined in the second module. This cannot
396     /// be represented as reachable because it can't handle the following case:
397     ///
398     /// pub mod n {                         // Should be `Public`
399     ///     pub(crate) mod p {              // Should *not* be accessible
400     ///         pub fn f() -> i32 { 12 }    // Must be `Reachable`
401     ///     }
402     /// }
403     /// pub macro m() {
404     ///     n::p::f()
405     /// }
406     macro_reachable: FxHashSet<(LocalDefId, LocalDefId)>,
407     /// Previous accessibility level; `None` means unreachable.
408     prev_level: Option<AccessLevel>,
409     /// Has something changed in the level map?
410     changed: bool,
411 }
412
413 struct ReachEverythingInTheInterfaceVisitor<'a, 'tcx> {
414     access_level: Option<AccessLevel>,
415     item_def_id: LocalDefId,
416     ev: &'a mut EmbargoVisitor<'tcx>,
417 }
418
419 impl<'tcx> EmbargoVisitor<'tcx> {
420     fn get(&self, def_id: LocalDefId) -> Option<AccessLevel> {
421         self.access_levels.map.get(&def_id).copied()
422     }
423
424     fn update_with_hir_id(
425         &mut self,
426         hir_id: hir::HirId,
427         level: Option<AccessLevel>,
428     ) -> Option<AccessLevel> {
429         let def_id = self.tcx.hir().local_def_id(hir_id);
430         self.update(def_id, level)
431     }
432
433     /// Updates node level and returns the updated level.
434     fn update(&mut self, def_id: LocalDefId, level: Option<AccessLevel>) -> Option<AccessLevel> {
435         let old_level = self.get(def_id);
436         // Accessibility levels can only grow.
437         if level > old_level {
438             self.access_levels.map.insert(def_id, level.unwrap());
439             self.changed = true;
440             level
441         } else {
442             old_level
443         }
444     }
445
446     fn reach(
447         &mut self,
448         def_id: LocalDefId,
449         access_level: Option<AccessLevel>,
450     ) -> ReachEverythingInTheInterfaceVisitor<'_, 'tcx> {
451         ReachEverythingInTheInterfaceVisitor {
452             access_level: cmp::min(access_level, Some(AccessLevel::Reachable)),
453             item_def_id: def_id,
454             ev: self,
455         }
456     }
457
458     // We have to make sure that the items that macros might reference
459     // are reachable, since they might be exported transitively.
460     fn update_reachability_from_macro(&mut self, local_def_id: LocalDefId, md: &MacroDef) {
461         // Non-opaque macros cannot make other items more accessible than they already are.
462
463         let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id);
464         let attrs = self.tcx.hir().attrs(hir_id);
465         if attr::find_transparency(attrs, md.macro_rules).0 != Transparency::Opaque {
466             return;
467         }
468
469         let macro_module_def_id = self.tcx.local_parent(local_def_id);
470         if self.tcx.hir().opt_def_kind(macro_module_def_id) != Some(DefKind::Mod) {
471             // The macro's parent doesn't correspond to a `mod`, return early (#63164, #65252).
472             return;
473         }
474
475         if self.get(local_def_id).is_none() {
476             return;
477         }
478
479         // Since we are starting from an externally visible module,
480         // all the parents in the loop below are also guaranteed to be modules.
481         let mut module_def_id = macro_module_def_id;
482         loop {
483             let changed_reachability =
484                 self.update_macro_reachable(module_def_id, macro_module_def_id);
485             if changed_reachability || module_def_id == CRATE_DEF_ID {
486                 break;
487             }
488             module_def_id = self.tcx.local_parent(module_def_id);
489         }
490     }
491
492     /// Updates the item as being reachable through a macro defined in the given
493     /// module. Returns `true` if the level has changed.
494     fn update_macro_reachable(
495         &mut self,
496         module_def_id: LocalDefId,
497         defining_mod: LocalDefId,
498     ) -> bool {
499         if self.macro_reachable.insert((module_def_id, defining_mod)) {
500             self.update_macro_reachable_mod(module_def_id, defining_mod);
501             true
502         } else {
503             false
504         }
505     }
506
507     fn update_macro_reachable_mod(&mut self, module_def_id: LocalDefId, defining_mod: LocalDefId) {
508         let module = self.tcx.hir().get_module(module_def_id).0;
509         for item_id in module.item_ids {
510             let def_kind = self.tcx.def_kind(item_id.def_id);
511             let vis = self.tcx.visibility(item_id.def_id);
512             self.update_macro_reachable_def(item_id.def_id, def_kind, vis, defining_mod);
513         }
514         if let Some(exports) = self.tcx.module_reexports(module_def_id) {
515             for export in exports {
516                 if export.vis.is_accessible_from(defining_mod.to_def_id(), self.tcx) {
517                     if let Res::Def(def_kind, def_id) = export.res {
518                         if let Some(def_id) = def_id.as_local() {
519                             let vis = self.tcx.visibility(def_id.to_def_id());
520                             self.update_macro_reachable_def(def_id, def_kind, vis, defining_mod);
521                         }
522                     }
523                 }
524             }
525         }
526     }
527
528     fn update_macro_reachable_def(
529         &mut self,
530         def_id: LocalDefId,
531         def_kind: DefKind,
532         vis: ty::Visibility,
533         module: LocalDefId,
534     ) {
535         let level = Some(AccessLevel::Reachable);
536         if vis.is_public() {
537             self.update(def_id, level);
538         }
539         match def_kind {
540             // No type privacy, so can be directly marked as reachable.
541             DefKind::Const | DefKind::Static(_) | DefKind::TraitAlias | DefKind::TyAlias => {
542                 if vis.is_accessible_from(module.to_def_id(), self.tcx) {
543                     self.update(def_id, level);
544                 }
545             }
546
547             // Hygiene isn't really implemented for `macro_rules!` macros at the
548             // moment. Accordingly, marking them as reachable is unwise. `macro` macros
549             // have normal hygiene, so we can treat them like other items without type
550             // privacy and mark them reachable.
551             DefKind::Macro(_) => {
552                 let item = self.tcx.hir().expect_item(def_id);
553                 if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }, _) = item.kind {
554                     if vis.is_accessible_from(module.to_def_id(), self.tcx) {
555                         self.update(def_id, level);
556                     }
557                 }
558             }
559
560             // We can't use a module name as the final segment of a path, except
561             // in use statements. Since re-export checking doesn't consider
562             // hygiene these don't need to be marked reachable. The contents of
563             // the module, however may be reachable.
564             DefKind::Mod => {
565                 if vis.is_accessible_from(module.to_def_id(), self.tcx) {
566                     self.update_macro_reachable(def_id, module);
567                 }
568             }
569
570             DefKind::Struct | DefKind::Union => {
571                 // While structs and unions have type privacy, their fields do not.
572                 if vis.is_public() {
573                     let item = self.tcx.hir().expect_item(def_id);
574                     if let hir::ItemKind::Struct(ref struct_def, _)
575                     | hir::ItemKind::Union(ref struct_def, _) = item.kind
576                     {
577                         for field in struct_def.fields() {
578                             let def_id = self.tcx.hir().local_def_id(field.hir_id);
579                             let field_vis = self.tcx.visibility(def_id);
580                             if field_vis.is_accessible_from(module.to_def_id(), self.tcx) {
581                                 self.reach(def_id, level).ty();
582                             }
583                         }
584                     } else {
585                         bug!("item {:?} with DefKind {:?}", item, def_kind);
586                     }
587                 }
588             }
589
590             // These have type privacy, so are not reachable unless they're
591             // public, or are not namespaced at all.
592             DefKind::AssocConst
593             | DefKind::AssocTy
594             | DefKind::ConstParam
595             | DefKind::Ctor(_, _)
596             | DefKind::Enum
597             | DefKind::ForeignTy
598             | DefKind::Fn
599             | DefKind::OpaqueTy
600             | DefKind::AssocFn
601             | DefKind::Trait
602             | DefKind::TyParam
603             | DefKind::Variant
604             | DefKind::LifetimeParam
605             | DefKind::ExternCrate
606             | DefKind::Use
607             | DefKind::ForeignMod
608             | DefKind::AnonConst
609             | DefKind::InlineConst
610             | DefKind::Field
611             | DefKind::GlobalAsm
612             | DefKind::Impl
613             | DefKind::Closure
614             | DefKind::Generator => (),
615         }
616     }
617 }
618
619 impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
620     type NestedFilter = nested_filter::All;
621
622     /// We want to visit items in the context of their containing
623     /// module and so forth, so supply a crate for doing a deep walk.
624     fn nested_visit_map(&mut self) -> Self::Map {
625         self.tcx.hir()
626     }
627
628     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
629         let item_level = match item.kind {
630             hir::ItemKind::Impl { .. } => {
631                 let impl_level =
632                     Option::<AccessLevel>::of_impl(item.def_id, self.tcx, &self.access_levels);
633                 self.update(item.def_id, impl_level)
634             }
635             _ => self.get(item.def_id),
636         };
637
638         // Update levels of nested things.
639         match item.kind {
640             hir::ItemKind::Enum(ref def, _) => {
641                 for variant in def.variants {
642                     let variant_level = self.update_with_hir_id(variant.id, item_level);
643                     if let Some(ctor_hir_id) = variant.data.ctor_hir_id() {
644                         self.update_with_hir_id(ctor_hir_id, item_level);
645                     }
646                     for field in variant.data.fields() {
647                         self.update_with_hir_id(field.hir_id, variant_level);
648                     }
649                 }
650             }
651             hir::ItemKind::Impl(ref impl_) => {
652                 for impl_item_ref in impl_.items {
653                     if impl_.of_trait.is_some()
654                         || self.tcx.visibility(impl_item_ref.id.def_id) == ty::Visibility::Public
655                     {
656                         self.update(impl_item_ref.id.def_id, item_level);
657                     }
658                 }
659             }
660             hir::ItemKind::Trait(.., trait_item_refs) => {
661                 for trait_item_ref in trait_item_refs {
662                     self.update(trait_item_ref.id.def_id, item_level);
663                 }
664             }
665             hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => {
666                 if let Some(ctor_hir_id) = def.ctor_hir_id() {
667                     self.update_with_hir_id(ctor_hir_id, item_level);
668                 }
669                 for field in def.fields() {
670                     let def_id = self.tcx.hir().local_def_id(field.hir_id);
671                     let vis = self.tcx.visibility(def_id);
672                     if vis.is_public() {
673                         self.update_with_hir_id(field.hir_id, item_level);
674                     }
675                 }
676             }
677             hir::ItemKind::Macro(ref macro_def, _) => {
678                 self.update_reachability_from_macro(item.def_id, macro_def);
679             }
680             hir::ItemKind::ForeignMod { items, .. } => {
681                 for foreign_item in items {
682                     if self.tcx.visibility(foreign_item.id.def_id) == ty::Visibility::Public {
683                         self.update(foreign_item.id.def_id, item_level);
684                     }
685                 }
686             }
687
688             hir::ItemKind::OpaqueTy(..)
689             | hir::ItemKind::Use(..)
690             | hir::ItemKind::Static(..)
691             | hir::ItemKind::Const(..)
692             | hir::ItemKind::GlobalAsm(..)
693             | hir::ItemKind::TyAlias(..)
694             | hir::ItemKind::Mod(..)
695             | hir::ItemKind::TraitAlias(..)
696             | hir::ItemKind::Fn(..)
697             | hir::ItemKind::ExternCrate(..) => {}
698         }
699
700         // Mark all items in interfaces of reachable items as reachable.
701         match item.kind {
702             // The interface is empty.
703             hir::ItemKind::Macro(..) | hir::ItemKind::ExternCrate(..) => {}
704             // All nested items are checked by `visit_item`.
705             hir::ItemKind::Mod(..) => {}
706             // Handled in the access level of in rustc_resolve
707             hir::ItemKind::Use(..) => {}
708             // The interface is empty.
709             hir::ItemKind::GlobalAsm(..) => {}
710             hir::ItemKind::OpaqueTy(..) => {
711                 // HACK(jynelson): trying to infer the type of `impl trait` breaks `async-std` (and `pub async fn` in general)
712                 // Since rustdoc never needs to do codegen and doesn't care about link-time reachability,
713                 // mark this as unreachable.
714                 // See https://github.com/rust-lang/rust/issues/75100
715                 if !self.tcx.sess.opts.actually_rustdoc {
716                     // FIXME: This is some serious pessimization intended to workaround deficiencies
717                     // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
718                     // reachable if they are returned via `impl Trait`, even from private functions.
719                     let exist_level =
720                         cmp::max(item_level, Some(AccessLevel::ReachableFromImplTrait));
721                     self.reach(item.def_id, exist_level).generics().predicates().ty();
722                 }
723             }
724             // Visit everything.
725             hir::ItemKind::Const(..)
726             | hir::ItemKind::Static(..)
727             | hir::ItemKind::Fn(..)
728             | hir::ItemKind::TyAlias(..) => {
729                 if item_level.is_some() {
730                     self.reach(item.def_id, item_level).generics().predicates().ty();
731                 }
732             }
733             hir::ItemKind::Trait(.., trait_item_refs) => {
734                 if item_level.is_some() {
735                     self.reach(item.def_id, item_level).generics().predicates();
736
737                     for trait_item_ref in trait_item_refs {
738                         let mut reach = self.reach(trait_item_ref.id.def_id, item_level);
739                         reach.generics().predicates();
740
741                         if trait_item_ref.kind == AssocItemKind::Type
742                             && !trait_item_ref.defaultness.has_value()
743                         {
744                             // No type to visit.
745                         } else {
746                             reach.ty();
747                         }
748                     }
749                 }
750             }
751             hir::ItemKind::TraitAlias(..) => {
752                 if item_level.is_some() {
753                     self.reach(item.def_id, item_level).generics().predicates();
754                 }
755             }
756             // Visit everything except for private impl items.
757             hir::ItemKind::Impl(ref impl_) => {
758                 if item_level.is_some() {
759                     self.reach(item.def_id, item_level).generics().predicates().ty().trait_ref();
760
761                     for impl_item_ref in impl_.items {
762                         let impl_item_level = self.get(impl_item_ref.id.def_id);
763                         if impl_item_level.is_some() {
764                             self.reach(impl_item_ref.id.def_id, impl_item_level)
765                                 .generics()
766                                 .predicates()
767                                 .ty();
768                         }
769                     }
770                 }
771             }
772
773             // Visit everything, but enum variants have their own levels.
774             hir::ItemKind::Enum(ref def, _) => {
775                 if item_level.is_some() {
776                     self.reach(item.def_id, item_level).generics().predicates();
777                 }
778                 for variant in def.variants {
779                     let variant_level = self.get(self.tcx.hir().local_def_id(variant.id));
780                     if variant_level.is_some() {
781                         for field in variant.data.fields() {
782                             self.reach(self.tcx.hir().local_def_id(field.hir_id), variant_level)
783                                 .ty();
784                         }
785                         // Corner case: if the variant is reachable, but its
786                         // enum is not, make the enum reachable as well.
787                         self.reach(item.def_id, variant_level).ty();
788                     }
789                     if let Some(hir_id) = variant.data.ctor_hir_id() {
790                         let ctor_def_id = self.tcx.hir().local_def_id(hir_id);
791                         let ctor_level = self.get(ctor_def_id);
792                         if ctor_level.is_some() {
793                             self.reach(item.def_id, ctor_level).ty();
794                         }
795                     }
796                 }
797             }
798             // Visit everything, but foreign items have their own levels.
799             hir::ItemKind::ForeignMod { items, .. } => {
800                 for foreign_item in items {
801                     let foreign_item_level = self.get(foreign_item.id.def_id);
802                     if foreign_item_level.is_some() {
803                         self.reach(foreign_item.id.def_id, foreign_item_level)
804                             .generics()
805                             .predicates()
806                             .ty();
807                     }
808                 }
809             }
810             // Visit everything except for private fields.
811             hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => {
812                 if item_level.is_some() {
813                     self.reach(item.def_id, item_level).generics().predicates();
814                     for field in struct_def.fields() {
815                         let def_id = self.tcx.hir().local_def_id(field.hir_id);
816                         let field_level = self.get(def_id);
817                         if field_level.is_some() {
818                             self.reach(def_id, field_level).ty();
819                         }
820                     }
821                 }
822                 if let Some(hir_id) = struct_def.ctor_hir_id() {
823                     let ctor_def_id = self.tcx.hir().local_def_id(hir_id);
824                     let ctor_level = self.get(ctor_def_id);
825                     if ctor_level.is_some() {
826                         self.reach(item.def_id, ctor_level).ty();
827                     }
828                 }
829             }
830         }
831
832         let orig_level = mem::replace(&mut self.prev_level, item_level);
833         intravisit::walk_item(self, item);
834         self.prev_level = orig_level;
835     }
836
837     fn visit_block(&mut self, b: &'tcx hir::Block<'tcx>) {
838         // Blocks can have public items, for example impls, but they always
839         // start as completely private regardless of publicity of a function,
840         // constant, type, field, etc., in which this block resides.
841         let orig_level = mem::replace(&mut self.prev_level, None);
842         intravisit::walk_block(self, b);
843         self.prev_level = orig_level;
844     }
845 }
846
847 impl ReachEverythingInTheInterfaceVisitor<'_, '_> {
848     fn generics(&mut self) -> &mut Self {
849         for param in &self.ev.tcx.generics_of(self.item_def_id).params {
850             match param.kind {
851                 GenericParamDefKind::Lifetime => {}
852                 GenericParamDefKind::Type { has_default, .. } => {
853                     if has_default {
854                         self.visit(self.ev.tcx.type_of(param.def_id));
855                     }
856                 }
857                 GenericParamDefKind::Const { has_default } => {
858                     self.visit(self.ev.tcx.type_of(param.def_id));
859                     if has_default {
860                         self.visit(self.ev.tcx.const_param_default(param.def_id));
861                     }
862                 }
863             }
864         }
865         self
866     }
867
868     fn predicates(&mut self) -> &mut Self {
869         self.visit_predicates(self.ev.tcx.predicates_of(self.item_def_id));
870         self
871     }
872
873     fn ty(&mut self) -> &mut Self {
874         self.visit(self.ev.tcx.type_of(self.item_def_id));
875         self
876     }
877
878     fn trait_ref(&mut self) -> &mut Self {
879         if let Some(trait_ref) = self.ev.tcx.impl_trait_ref(self.item_def_id) {
880             self.visit_trait(trait_ref);
881         }
882         self
883     }
884 }
885
886 impl<'tcx> DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx> {
887     fn tcx(&self) -> TyCtxt<'tcx> {
888         self.ev.tcx
889     }
890     fn visit_def_id(
891         &mut self,
892         def_id: DefId,
893         _kind: &str,
894         _descr: &dyn fmt::Display,
895     ) -> ControlFlow<Self::BreakTy> {
896         if let Some(def_id) = def_id.as_local() {
897             if let (ty::Visibility::Public, _) | (_, Some(AccessLevel::ReachableFromImplTrait)) =
898                 (self.tcx().visibility(def_id.to_def_id()), self.access_level)
899             {
900                 self.ev.update(def_id, self.access_level);
901             }
902         }
903         ControlFlow::CONTINUE
904     }
905 }
906
907 //////////////////////////////////////////////////////////////////////////////////////
908 /// Name privacy visitor, checks privacy and reports violations.
909 /// Most of name privacy checks are performed during the main resolution phase,
910 /// or later in type checking when field accesses and associated items are resolved.
911 /// This pass performs remaining checks for fields in struct expressions and patterns.
912 //////////////////////////////////////////////////////////////////////////////////////
913
914 struct NamePrivacyVisitor<'tcx> {
915     tcx: TyCtxt<'tcx>,
916     maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
917     current_item: LocalDefId,
918 }
919
920 impl<'tcx> NamePrivacyVisitor<'tcx> {
921     /// Gets the type-checking results for the current body.
922     /// As this will ICE if called outside bodies, only call when working with
923     /// `Expr` or `Pat` nodes (they are guaranteed to be found only in bodies).
924     #[track_caller]
925     fn typeck_results(&self) -> &'tcx ty::TypeckResults<'tcx> {
926         self.maybe_typeck_results
927             .expect("`NamePrivacyVisitor::typeck_results` called outside of body")
928     }
929
930     // Checks that a field in a struct constructor (expression or pattern) is accessible.
931     fn check_field(
932         &mut self,
933         use_ctxt: Span,        // syntax context of the field name at the use site
934         span: Span,            // span of the field pattern, e.g., `x: 0`
935         def: ty::AdtDef<'tcx>, // definition of the struct or enum
936         field: &'tcx ty::FieldDef,
937         in_update_syntax: bool,
938     ) {
939         if def.is_enum() {
940             return;
941         }
942
943         // definition of the field
944         let ident = Ident::new(kw::Empty, use_ctxt);
945         let hir_id = self.tcx.hir().local_def_id_to_hir_id(self.current_item);
946         let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did(), hir_id).1;
947         if !field.vis.is_accessible_from(def_id, self.tcx) {
948             self.tcx.sess.emit_err(FieldIsPrivate {
949                 span,
950                 field_name: field.name,
951                 variant_descr: def.variant_descr(),
952                 def_path_str: self.tcx.def_path_str(def.did()),
953                 label: if in_update_syntax {
954                     FieldIsPrivateLabel::IsUpdateSyntax { span, field_name: field.name }
955                 } else {
956                     FieldIsPrivateLabel::Other { span }
957                 },
958             });
959         }
960     }
961 }
962
963 impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
964     type NestedFilter = nested_filter::All;
965
966     /// We want to visit items in the context of their containing
967     /// module and so forth, so supply a crate for doing a deep walk.
968     fn nested_visit_map(&mut self) -> Self::Map {
969         self.tcx.hir()
970     }
971
972     fn visit_mod(&mut self, _m: &'tcx hir::Mod<'tcx>, _s: Span, _n: hir::HirId) {
973         // Don't visit nested modules, since we run a separate visitor walk
974         // for each module in `privacy_access_levels`
975     }
976
977     fn visit_nested_body(&mut self, body: hir::BodyId) {
978         let old_maybe_typeck_results =
979             self.maybe_typeck_results.replace(self.tcx.typeck_body(body));
980         let body = self.tcx.hir().body(body);
981         self.visit_body(body);
982         self.maybe_typeck_results = old_maybe_typeck_results;
983     }
984
985     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
986         let orig_current_item = mem::replace(&mut self.current_item, item.def_id);
987         intravisit::walk_item(self, item);
988         self.current_item = orig_current_item;
989     }
990
991     fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
992         if let hir::ExprKind::Struct(qpath, fields, ref base) = expr.kind {
993             let res = self.typeck_results().qpath_res(qpath, expr.hir_id);
994             let adt = self.typeck_results().expr_ty(expr).ty_adt_def().unwrap();
995             let variant = adt.variant_of_res(res);
996             if let Some(base) = *base {
997                 // If the expression uses FRU we need to make sure all the unmentioned fields
998                 // are checked for privacy (RFC 736). Rather than computing the set of
999                 // unmentioned fields, just check them all.
1000                 for (vf_index, variant_field) in variant.fields.iter().enumerate() {
1001                     let field = fields.iter().find(|f| {
1002                         self.tcx.field_index(f.hir_id, self.typeck_results()) == vf_index
1003                     });
1004                     let (use_ctxt, span) = match field {
1005                         Some(field) => (field.ident.span, field.span),
1006                         None => (base.span, base.span),
1007                     };
1008                     self.check_field(use_ctxt, span, adt, variant_field, true);
1009                 }
1010             } else {
1011                 for field in fields {
1012                     let use_ctxt = field.ident.span;
1013                     let index = self.tcx.field_index(field.hir_id, self.typeck_results());
1014                     self.check_field(use_ctxt, field.span, adt, &variant.fields[index], false);
1015                 }
1016             }
1017         }
1018
1019         intravisit::walk_expr(self, expr);
1020     }
1021
1022     fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) {
1023         if let PatKind::Struct(ref qpath, fields, _) = pat.kind {
1024             let res = self.typeck_results().qpath_res(qpath, pat.hir_id);
1025             let adt = self.typeck_results().pat_ty(pat).ty_adt_def().unwrap();
1026             let variant = adt.variant_of_res(res);
1027             for field in fields {
1028                 let use_ctxt = field.ident.span;
1029                 let index = self.tcx.field_index(field.hir_id, self.typeck_results());
1030                 self.check_field(use_ctxt, field.span, adt, &variant.fields[index], false);
1031             }
1032         }
1033
1034         intravisit::walk_pat(self, pat);
1035     }
1036 }
1037
1038 ////////////////////////////////////////////////////////////////////////////////////////////
1039 /// Type privacy visitor, checks types for privacy and reports violations.
1040 /// Both explicitly written types and inferred types of expressions and patterns are checked.
1041 /// Checks are performed on "semantic" types regardless of names and their hygiene.
1042 ////////////////////////////////////////////////////////////////////////////////////////////
1043
1044 struct TypePrivacyVisitor<'tcx> {
1045     tcx: TyCtxt<'tcx>,
1046     maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
1047     current_item: LocalDefId,
1048     span: Span,
1049 }
1050
1051 impl<'tcx> TypePrivacyVisitor<'tcx> {
1052     /// Gets the type-checking results for the current body.
1053     /// As this will ICE if called outside bodies, only call when working with
1054     /// `Expr` or `Pat` nodes (they are guaranteed to be found only in bodies).
1055     #[track_caller]
1056     fn typeck_results(&self) -> &'tcx ty::TypeckResults<'tcx> {
1057         self.maybe_typeck_results
1058             .expect("`TypePrivacyVisitor::typeck_results` called outside of body")
1059     }
1060
1061     fn item_is_accessible(&self, did: DefId) -> bool {
1062         self.tcx.visibility(did).is_accessible_from(self.current_item.to_def_id(), self.tcx)
1063     }
1064
1065     // Take node-id of an expression or pattern and check its type for privacy.
1066     fn check_expr_pat_type(&mut self, id: hir::HirId, span: Span) -> bool {
1067         self.span = span;
1068         let typeck_results = self.typeck_results();
1069         let result: ControlFlow<()> = try {
1070             self.visit(typeck_results.node_type(id))?;
1071             self.visit(typeck_results.node_substs(id))?;
1072             if let Some(adjustments) = typeck_results.adjustments().get(id) {
1073                 adjustments.iter().try_for_each(|adjustment| self.visit(adjustment.target))?;
1074             }
1075         };
1076         result.is_break()
1077     }
1078
1079     fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool {
1080         let is_error = !self.item_is_accessible(def_id);
1081         if is_error {
1082             self.tcx.sess.emit_err(ItemIsPrivate {
1083                 span: self.span,
1084                 kind,
1085                 descr: descr.to_string(),
1086             });
1087         }
1088         is_error
1089     }
1090 }
1091
1092 impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
1093     type NestedFilter = nested_filter::All;
1094
1095     /// We want to visit items in the context of their containing
1096     /// module and so forth, so supply a crate for doing a deep walk.
1097     fn nested_visit_map(&mut self) -> Self::Map {
1098         self.tcx.hir()
1099     }
1100
1101     fn visit_mod(&mut self, _m: &'tcx hir::Mod<'tcx>, _s: Span, _n: hir::HirId) {
1102         // Don't visit nested modules, since we run a separate visitor walk
1103         // for each module in `privacy_access_levels`
1104     }
1105
1106     fn visit_nested_body(&mut self, body: hir::BodyId) {
1107         let old_maybe_typeck_results =
1108             self.maybe_typeck_results.replace(self.tcx.typeck_body(body));
1109         let body = self.tcx.hir().body(body);
1110         self.visit_body(body);
1111         self.maybe_typeck_results = old_maybe_typeck_results;
1112     }
1113
1114     fn visit_generic_arg(&mut self, generic_arg: &'tcx hir::GenericArg<'tcx>) {
1115         match generic_arg {
1116             hir::GenericArg::Type(t) => self.visit_ty(t),
1117             hir::GenericArg::Infer(inf) => self.visit_infer(inf),
1118             hir::GenericArg::Lifetime(_) | hir::GenericArg::Const(_) => {}
1119         }
1120     }
1121
1122     fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) {
1123         self.span = hir_ty.span;
1124         if let Some(typeck_results) = self.maybe_typeck_results {
1125             // Types in bodies.
1126             if self.visit(typeck_results.node_type(hir_ty.hir_id)).is_break() {
1127                 return;
1128             }
1129         } else {
1130             // Types in signatures.
1131             // FIXME: This is very ineffective. Ideally each HIR type should be converted
1132             // into a semantic type only once and the result should be cached somehow.
1133             if self.visit(rustc_typeck::hir_ty_to_ty(self.tcx, hir_ty)).is_break() {
1134                 return;
1135             }
1136         }
1137
1138         intravisit::walk_ty(self, hir_ty);
1139     }
1140
1141     fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
1142         self.span = inf.span;
1143         if let Some(typeck_results) = self.maybe_typeck_results {
1144             if let Some(ty) = typeck_results.node_type_opt(inf.hir_id) {
1145                 if self.visit(ty).is_break() {
1146                     return;
1147                 }
1148             } else {
1149                 // We don't do anything for const infers here.
1150             }
1151         } else {
1152             bug!("visit_infer without typeck_results");
1153         }
1154         intravisit::walk_inf(self, inf);
1155     }
1156
1157     fn visit_trait_ref(&mut self, trait_ref: &'tcx hir::TraitRef<'tcx>) {
1158         self.span = trait_ref.path.span;
1159         if self.maybe_typeck_results.is_none() {
1160             // Avoid calling `hir_trait_to_predicates` in bodies, it will ICE.
1161             // The traits' privacy in bodies is already checked as a part of trait object types.
1162             let bounds = rustc_typeck::hir_trait_to_predicates(
1163                 self.tcx,
1164                 trait_ref,
1165                 // NOTE: This isn't really right, but the actual type doesn't matter here. It's
1166                 // just required by `ty::TraitRef`.
1167                 self.tcx.types.never,
1168             );
1169
1170             for (trait_predicate, _, _) in bounds.trait_bounds {
1171                 if self.visit_trait(trait_predicate.skip_binder()).is_break() {
1172                     return;
1173                 }
1174             }
1175
1176             for (poly_predicate, _) in bounds.projection_bounds {
1177                 let pred = poly_predicate.skip_binder();
1178                 let poly_pred_term = self.visit(pred.term);
1179                 if poly_pred_term.is_break()
1180                     || self.visit_projection_ty(pred.projection_ty).is_break()
1181                 {
1182                     return;
1183                 }
1184             }
1185         }
1186
1187         intravisit::walk_trait_ref(self, trait_ref);
1188     }
1189
1190     // Check types of expressions
1191     fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
1192         if self.check_expr_pat_type(expr.hir_id, expr.span) {
1193             // Do not check nested expressions if the error already happened.
1194             return;
1195         }
1196         match expr.kind {
1197             hir::ExprKind::Assign(_, rhs, _) | hir::ExprKind::Match(rhs, ..) => {
1198                 // Do not report duplicate errors for `x = y` and `match x { ... }`.
1199                 if self.check_expr_pat_type(rhs.hir_id, rhs.span) {
1200                     return;
1201                 }
1202             }
1203             hir::ExprKind::MethodCall(segment, ..) => {
1204                 // Method calls have to be checked specially.
1205                 self.span = segment.ident.span;
1206                 if let Some(def_id) = self.typeck_results().type_dependent_def_id(expr.hir_id) {
1207                     if self.visit(self.tcx.type_of(def_id)).is_break() {
1208                         return;
1209                     }
1210                 } else {
1211                     self.tcx
1212                         .sess
1213                         .delay_span_bug(expr.span, "no type-dependent def for method call");
1214                 }
1215             }
1216             _ => {}
1217         }
1218
1219         intravisit::walk_expr(self, expr);
1220     }
1221
1222     // Prohibit access to associated items with insufficient nominal visibility.
1223     //
1224     // Additionally, until better reachability analysis for macros 2.0 is available,
1225     // we prohibit access to private statics from other crates, this allows to give
1226     // more code internal visibility at link time. (Access to private functions
1227     // is already prohibited by type privacy for function types.)
1228     fn visit_qpath(&mut self, qpath: &'tcx hir::QPath<'tcx>, id: hir::HirId, span: Span) {
1229         let def = match qpath {
1230             hir::QPath::Resolved(_, path) => match path.res {
1231                 Res::Def(kind, def_id) => Some((kind, def_id)),
1232                 _ => None,
1233             },
1234             hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self
1235                 .maybe_typeck_results
1236                 .and_then(|typeck_results| typeck_results.type_dependent_def(id)),
1237         };
1238         let def = def.filter(|(kind, _)| {
1239             matches!(
1240                 kind,
1241                 DefKind::AssocFn | DefKind::AssocConst | DefKind::AssocTy | DefKind::Static(_)
1242             )
1243         });
1244         if let Some((kind, def_id)) = def {
1245             let is_local_static =
1246                 if let DefKind::Static(_) = kind { def_id.is_local() } else { false };
1247             if !self.item_is_accessible(def_id) && !is_local_static {
1248                 let sess = self.tcx.sess;
1249                 let sm = sess.source_map();
1250                 let name = match qpath {
1251                     hir::QPath::Resolved(..) | hir::QPath::LangItem(..) => {
1252                         sm.span_to_snippet(qpath.span()).ok()
1253                     }
1254                     hir::QPath::TypeRelative(_, segment) => Some(segment.ident.to_string()),
1255                 };
1256                 let kind = kind.descr(def_id);
1257                 let _ = match name {
1258                     Some(name) => sess.emit_err(ItemIsPrivate { span, kind, descr: name }),
1259                     None => sess.emit_err(UnnamedItemIsPrivate { span, kind }),
1260                 };
1261                 return;
1262             }
1263         }
1264
1265         intravisit::walk_qpath(self, qpath, id, span);
1266     }
1267
1268     // Check types of patterns.
1269     fn visit_pat(&mut self, pattern: &'tcx hir::Pat<'tcx>) {
1270         if self.check_expr_pat_type(pattern.hir_id, pattern.span) {
1271             // Do not check nested patterns if the error already happened.
1272             return;
1273         }
1274
1275         intravisit::walk_pat(self, pattern);
1276     }
1277
1278     fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
1279         if let Some(init) = local.init {
1280             if self.check_expr_pat_type(init.hir_id, init.span) {
1281                 // Do not report duplicate errors for `let x = y`.
1282                 return;
1283             }
1284         }
1285
1286         intravisit::walk_local(self, local);
1287     }
1288
1289     // Check types in item interfaces.
1290     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
1291         let orig_current_item = mem::replace(&mut self.current_item, item.def_id);
1292         let old_maybe_typeck_results = self.maybe_typeck_results.take();
1293         intravisit::walk_item(self, item);
1294         self.maybe_typeck_results = old_maybe_typeck_results;
1295         self.current_item = orig_current_item;
1296     }
1297 }
1298
1299 impl<'tcx> DefIdVisitor<'tcx> for TypePrivacyVisitor<'tcx> {
1300     fn tcx(&self) -> TyCtxt<'tcx> {
1301         self.tcx
1302     }
1303     fn visit_def_id(
1304         &mut self,
1305         def_id: DefId,
1306         kind: &str,
1307         descr: &dyn fmt::Display,
1308     ) -> ControlFlow<Self::BreakTy> {
1309         if self.check_def_id(def_id, kind, descr) {
1310             ControlFlow::BREAK
1311         } else {
1312             ControlFlow::CONTINUE
1313         }
1314     }
1315 }
1316
1317 ///////////////////////////////////////////////////////////////////////////////
1318 /// Obsolete visitors for checking for private items in public interfaces.
1319 /// These visitors are supposed to be kept in frozen state and produce an
1320 /// "old error node set". For backward compatibility the new visitor reports
1321 /// warnings instead of hard errors when the erroneous node is not in this old set.
1322 ///////////////////////////////////////////////////////////////////////////////
1323
1324 struct ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
1325     tcx: TyCtxt<'tcx>,
1326     access_levels: &'a AccessLevels,
1327     in_variant: bool,
1328     // Set of errors produced by this obsolete visitor.
1329     old_error_set: HirIdSet,
1330 }
1331
1332 struct ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
1333     inner: &'a ObsoleteVisiblePrivateTypesVisitor<'b, 'tcx>,
1334     /// Whether the type refers to private types.
1335     contains_private: bool,
1336     /// Whether we've recurred at all (i.e., if we're pointing at the
1337     /// first type on which `visit_ty` was called).
1338     at_outer_type: bool,
1339     /// Whether that first type is a public path.
1340     outer_type_is_public_path: bool,
1341 }
1342
1343 impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
1344     fn path_is_private_type(&self, path: &hir::Path<'_>) -> bool {
1345         let did = match path.res {
1346             Res::PrimTy(..) | Res::SelfTy { .. } | Res::Err => return false,
1347             res => res.def_id(),
1348         };
1349
1350         // A path can only be private if:
1351         // it's in this crate...
1352         if let Some(did) = did.as_local() {
1353             // .. and it corresponds to a private type in the AST (this returns
1354             // `None` for type parameters).
1355             match self.tcx.hir().find(self.tcx.hir().local_def_id_to_hir_id(did)) {
1356                 Some(Node::Item(_)) => !self.tcx.visibility(did).is_public(),
1357                 Some(_) | None => false,
1358             }
1359         } else {
1360             false
1361         }
1362     }
1363
1364     fn trait_is_public(&self, trait_id: LocalDefId) -> bool {
1365         // FIXME: this would preferably be using `exported_items`, but all
1366         // traits are exported currently (see `EmbargoVisitor.exported_trait`).
1367         self.access_levels.is_public(trait_id)
1368     }
1369
1370     fn check_generic_bound(&mut self, bound: &hir::GenericBound<'_>) {
1371         if let hir::GenericBound::Trait(ref trait_ref, _) = *bound {
1372             if self.path_is_private_type(trait_ref.trait_ref.path) {
1373                 self.old_error_set.insert(trait_ref.trait_ref.hir_ref_id);
1374             }
1375         }
1376     }
1377
1378     fn item_is_public(&self, def_id: LocalDefId) -> bool {
1379         self.access_levels.is_reachable(def_id) || self.tcx.visibility(def_id).is_public()
1380     }
1381 }
1382
1383 impl<'a, 'b, 'tcx, 'v> Visitor<'v> for ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
1384     fn visit_generic_arg(&mut self, generic_arg: &'v hir::GenericArg<'v>) {
1385         match generic_arg {
1386             hir::GenericArg::Type(t) => self.visit_ty(t),
1387             hir::GenericArg::Infer(inf) => self.visit_ty(&inf.to_ty()),
1388             hir::GenericArg::Lifetime(_) | hir::GenericArg::Const(_) => {}
1389         }
1390     }
1391
1392     fn visit_ty(&mut self, ty: &hir::Ty<'_>) {
1393         if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind {
1394             if self.inner.path_is_private_type(path) {
1395                 self.contains_private = true;
1396                 // Found what we're looking for, so let's stop working.
1397                 return;
1398             }
1399         }
1400         if let hir::TyKind::Path(_) = ty.kind {
1401             if self.at_outer_type {
1402                 self.outer_type_is_public_path = true;
1403             }
1404         }
1405         self.at_outer_type = false;
1406         intravisit::walk_ty(self, ty)
1407     }
1408
1409     // Don't want to recurse into `[, .. expr]`.
1410     fn visit_expr(&mut self, _: &hir::Expr<'_>) {}
1411 }
1412
1413 impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
1414     type NestedFilter = nested_filter::All;
1415
1416     /// We want to visit items in the context of their containing
1417     /// module and so forth, so supply a crate for doing a deep walk.
1418     fn nested_visit_map(&mut self) -> Self::Map {
1419         self.tcx.hir()
1420     }
1421
1422     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
1423         match item.kind {
1424             // Contents of a private mod can be re-exported, so we need
1425             // to check internals.
1426             hir::ItemKind::Mod(_) => {}
1427
1428             // An `extern {}` doesn't introduce a new privacy
1429             // namespace (the contents have their own privacies).
1430             hir::ItemKind::ForeignMod { .. } => {}
1431
1432             hir::ItemKind::Trait(.., bounds, _) => {
1433                 if !self.trait_is_public(item.def_id) {
1434                     return;
1435                 }
1436
1437                 for bound in bounds.iter() {
1438                     self.check_generic_bound(bound)
1439                 }
1440             }
1441
1442             // Impls need some special handling to try to offer useful
1443             // error messages without (too many) false positives
1444             // (i.e., we could just return here to not check them at
1445             // all, or some worse estimation of whether an impl is
1446             // publicly visible).
1447             hir::ItemKind::Impl(ref impl_) => {
1448                 // `impl [... for] Private` is never visible.
1449                 let self_contains_private;
1450                 // `impl [... for] Public<...>`, but not `impl [... for]
1451                 // Vec<Public>` or `(Public,)`, etc.
1452                 let self_is_public_path;
1453
1454                 // Check the properties of the `Self` type:
1455                 {
1456                     let mut visitor = ObsoleteCheckTypeForPrivatenessVisitor {
1457                         inner: self,
1458                         contains_private: false,
1459                         at_outer_type: true,
1460                         outer_type_is_public_path: false,
1461                     };
1462                     visitor.visit_ty(impl_.self_ty);
1463                     self_contains_private = visitor.contains_private;
1464                     self_is_public_path = visitor.outer_type_is_public_path;
1465                 }
1466
1467                 // Miscellaneous info about the impl:
1468
1469                 // `true` iff this is `impl Private for ...`.
1470                 let not_private_trait = impl_.of_trait.as_ref().map_or(
1471                     true, // no trait counts as public trait
1472                     |tr| {
1473                         if let Some(def_id) = tr.path.res.def_id().as_local() {
1474                             self.trait_is_public(def_id)
1475                         } else {
1476                             true // external traits must be public
1477                         }
1478                     },
1479                 );
1480
1481                 // `true` iff this is a trait impl or at least one method is public.
1482                 //
1483                 // `impl Public { $( fn ...() {} )* }` is not visible.
1484                 //
1485                 // This is required over just using the methods' privacy
1486                 // directly because we might have `impl<T: Foo<Private>> ...`,
1487                 // and we shouldn't warn about the generics if all the methods
1488                 // are private (because `T` won't be visible externally).
1489                 let trait_or_some_public_method = impl_.of_trait.is_some()
1490                     || impl_.items.iter().any(|impl_item_ref| {
1491                         let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
1492                         match impl_item.kind {
1493                             hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..) => {
1494                                 self.access_levels.is_reachable(impl_item_ref.id.def_id)
1495                             }
1496                             hir::ImplItemKind::TyAlias(_) => false,
1497                         }
1498                     });
1499
1500                 if !self_contains_private && not_private_trait && trait_or_some_public_method {
1501                     intravisit::walk_generics(self, &impl_.generics);
1502
1503                     match impl_.of_trait {
1504                         None => {
1505                             for impl_item_ref in impl_.items {
1506                                 // This is where we choose whether to walk down
1507                                 // further into the impl to check its items. We
1508                                 // should only walk into public items so that we
1509                                 // don't erroneously report errors for private
1510                                 // types in private items.
1511                                 let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
1512                                 match impl_item.kind {
1513                                     hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..)
1514                                         if self.item_is_public(impl_item.def_id) =>
1515                                     {
1516                                         intravisit::walk_impl_item(self, impl_item)
1517                                     }
1518                                     hir::ImplItemKind::TyAlias(..) => {
1519                                         intravisit::walk_impl_item(self, impl_item)
1520                                     }
1521                                     _ => {}
1522                                 }
1523                             }
1524                         }
1525                         Some(ref tr) => {
1526                             // Any private types in a trait impl fall into three
1527                             // categories.
1528                             // 1. mentioned in the trait definition
1529                             // 2. mentioned in the type params/generics
1530                             // 3. mentioned in the associated types of the impl
1531                             //
1532                             // Those in 1. can only occur if the trait is in
1533                             // this crate and will have been warned about on the
1534                             // trait definition (there's no need to warn twice
1535                             // so we don't check the methods).
1536                             //
1537                             // Those in 2. are warned via walk_generics and this
1538                             // call here.
1539                             intravisit::walk_path(self, tr.path);
1540
1541                             // Those in 3. are warned with this call.
1542                             for impl_item_ref in impl_.items {
1543                                 let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
1544                                 if let hir::ImplItemKind::TyAlias(ty) = impl_item.kind {
1545                                     self.visit_ty(ty);
1546                                 }
1547                             }
1548                         }
1549                     }
1550                 } else if impl_.of_trait.is_none() && self_is_public_path {
1551                     // `impl Public<Private> { ... }`. Any public static
1552                     // methods will be visible as `Public::foo`.
1553                     let mut found_pub_static = false;
1554                     for impl_item_ref in impl_.items {
1555                         if self.access_levels.is_reachable(impl_item_ref.id.def_id)
1556                             || self.tcx.visibility(impl_item_ref.id.def_id)
1557                                 == ty::Visibility::Public
1558                         {
1559                             let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
1560                             match impl_item_ref.kind {
1561                                 AssocItemKind::Const => {
1562                                     found_pub_static = true;
1563                                     intravisit::walk_impl_item(self, impl_item);
1564                                 }
1565                                 AssocItemKind::Fn { has_self: false } => {
1566                                     found_pub_static = true;
1567                                     intravisit::walk_impl_item(self, impl_item);
1568                                 }
1569                                 _ => {}
1570                             }
1571                         }
1572                     }
1573                     if found_pub_static {
1574                         intravisit::walk_generics(self, &impl_.generics)
1575                     }
1576                 }
1577                 return;
1578             }
1579
1580             // `type ... = ...;` can contain private types, because
1581             // we're introducing a new name.
1582             hir::ItemKind::TyAlias(..) => return,
1583
1584             // Not at all public, so we don't care.
1585             _ if !self.item_is_public(item.def_id) => {
1586                 return;
1587             }
1588
1589             _ => {}
1590         }
1591
1592         // We've carefully constructed it so that if we're here, then
1593         // any `visit_ty`'s will be called on things that are in
1594         // public signatures, i.e., things that we're interested in for
1595         // this visitor.
1596         intravisit::walk_item(self, item);
1597     }
1598
1599     fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
1600         for predicate in generics.predicates {
1601             match predicate {
1602                 hir::WherePredicate::BoundPredicate(bound_pred) => {
1603                     for bound in bound_pred.bounds.iter() {
1604                         self.check_generic_bound(bound)
1605                     }
1606                 }
1607                 hir::WherePredicate::RegionPredicate(_) => {}
1608                 hir::WherePredicate::EqPredicate(eq_pred) => {
1609                     self.visit_ty(eq_pred.rhs_ty);
1610                 }
1611             }
1612         }
1613     }
1614
1615     fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
1616         if self.access_levels.is_reachable(item.def_id) {
1617             intravisit::walk_foreign_item(self, item)
1618         }
1619     }
1620
1621     fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) {
1622         if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = t.kind {
1623             if self.path_is_private_type(path) {
1624                 self.old_error_set.insert(t.hir_id);
1625             }
1626         }
1627         intravisit::walk_ty(self, t)
1628     }
1629
1630     fn visit_variant(
1631         &mut self,
1632         v: &'tcx hir::Variant<'tcx>,
1633         g: &'tcx hir::Generics<'tcx>,
1634         item_id: hir::HirId,
1635     ) {
1636         if self.access_levels.is_reachable(self.tcx.hir().local_def_id(v.id)) {
1637             self.in_variant = true;
1638             intravisit::walk_variant(self, v, g, item_id);
1639             self.in_variant = false;
1640         }
1641     }
1642
1643     fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) {
1644         let def_id = self.tcx.hir().local_def_id(s.hir_id);
1645         let vis = self.tcx.visibility(def_id);
1646         if vis.is_public() || self.in_variant {
1647             intravisit::walk_field_def(self, s);
1648         }
1649     }
1650
1651     // We don't need to introspect into these at all: an
1652     // expression/block context can't possibly contain exported things.
1653     // (Making them no-ops stops us from traversing the whole AST without
1654     // having to be super careful about our `walk_...` calls above.)
1655     fn visit_block(&mut self, _: &'tcx hir::Block<'tcx>) {}
1656     fn visit_expr(&mut self, _: &'tcx hir::Expr<'tcx>) {}
1657 }
1658
1659 ///////////////////////////////////////////////////////////////////////////////
1660 /// SearchInterfaceForPrivateItemsVisitor traverses an item's interface and
1661 /// finds any private components in it.
1662 /// PrivateItemsInPublicInterfacesVisitor ensures there are no private types
1663 /// and traits in public interfaces.
1664 ///////////////////////////////////////////////////////////////////////////////
1665
1666 struct SearchInterfaceForPrivateItemsVisitor<'tcx> {
1667     tcx: TyCtxt<'tcx>,
1668     item_def_id: LocalDefId,
1669     /// The visitor checks that each component type is at least this visible.
1670     required_visibility: ty::Visibility,
1671     has_old_errors: bool,
1672     in_assoc_ty: bool,
1673 }
1674
1675 impl SearchInterfaceForPrivateItemsVisitor<'_> {
1676     fn generics(&mut self) -> &mut Self {
1677         for param in &self.tcx.generics_of(self.item_def_id).params {
1678             match param.kind {
1679                 GenericParamDefKind::Lifetime => {}
1680                 GenericParamDefKind::Type { has_default, .. } => {
1681                     if has_default {
1682                         self.visit(self.tcx.type_of(param.def_id));
1683                     }
1684                 }
1685                 // FIXME(generic_const_exprs): May want to look inside const here
1686                 GenericParamDefKind::Const { .. } => {
1687                     self.visit(self.tcx.type_of(param.def_id));
1688                 }
1689             }
1690         }
1691         self
1692     }
1693
1694     fn predicates(&mut self) -> &mut Self {
1695         // N.B., we use `explicit_predicates_of` and not `predicates_of`
1696         // because we don't want to report privacy errors due to where
1697         // clauses that the compiler inferred. We only want to
1698         // consider the ones that the user wrote. This is important
1699         // for the inferred outlives rules; see
1700         // `src/test/ui/rfc-2093-infer-outlives/privacy.rs`.
1701         self.visit_predicates(self.tcx.explicit_predicates_of(self.item_def_id));
1702         self
1703     }
1704
1705     fn bounds(&mut self) -> &mut Self {
1706         self.visit_predicates(ty::GenericPredicates {
1707             parent: None,
1708             predicates: self.tcx.explicit_item_bounds(self.item_def_id),
1709         });
1710         self
1711     }
1712
1713     fn ty(&mut self) -> &mut Self {
1714         self.visit(self.tcx.type_of(self.item_def_id));
1715         self
1716     }
1717
1718     fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool {
1719         if self.leaks_private_dep(def_id) {
1720             self.tcx.struct_span_lint_hir(
1721                 lint::builtin::EXPORTED_PRIVATE_DEPENDENCIES,
1722                 self.tcx.hir().local_def_id_to_hir_id(self.item_def_id),
1723                 self.tcx.def_span(self.item_def_id.to_def_id()),
1724                 |lint| {
1725                     lint.build(&format!(
1726                         "{} `{}` from private dependency '{}' in public \
1727                                                 interface",
1728                         kind,
1729                         descr,
1730                         self.tcx.crate_name(def_id.krate)
1731                     ))
1732                     .emit();
1733                 },
1734             );
1735         }
1736
1737         let hir_id = match def_id.as_local() {
1738             Some(def_id) => self.tcx.hir().local_def_id_to_hir_id(def_id),
1739             None => return false,
1740         };
1741
1742         let vis = self.tcx.visibility(def_id);
1743         if !vis.is_at_least(self.required_visibility, self.tcx) {
1744             let vis_descr = match vis {
1745                 ty::Visibility::Public => "public",
1746                 ty::Visibility::Invisible => "private",
1747                 ty::Visibility::Restricted(vis_def_id) => {
1748                     if vis_def_id == self.tcx.parent_module(hir_id).to_def_id() {
1749                         "private"
1750                     } else if vis_def_id.is_top_level_module() {
1751                         "crate-private"
1752                     } else {
1753                         "restricted"
1754                     }
1755                 }
1756             };
1757             let span = self.tcx.def_span(self.item_def_id.to_def_id());
1758             if self.has_old_errors
1759                 || self.in_assoc_ty
1760                 || self.tcx.resolutions(()).has_pub_restricted
1761             {
1762                 let descr = descr.to_string();
1763                 let vis_span =
1764                     self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id));
1765                 if kind == "trait" {
1766                     self.tcx.sess.emit_err(InPublicInterfaceTraits {
1767                         span,
1768                         vis_descr,
1769                         kind,
1770                         descr,
1771                         vis_span,
1772                     });
1773                 } else {
1774                     self.tcx.sess.emit_err(InPublicInterface {
1775                         span,
1776                         vis_descr,
1777                         kind,
1778                         descr,
1779                         vis_span,
1780                     });
1781                 }
1782             } else {
1783                 let err_code = if kind == "trait" { "E0445" } else { "E0446" };
1784                 self.tcx.struct_span_lint_hir(
1785                     lint::builtin::PRIVATE_IN_PUBLIC,
1786                     hir_id,
1787                     span,
1788                     |lint| {
1789                         lint.build(&format!(
1790                             "{} (error {})",
1791                             format!("{} {} `{}` in public interface", vis_descr, kind, descr),
1792                             err_code
1793                         ))
1794                         .emit();
1795                     },
1796                 );
1797             }
1798         }
1799
1800         false
1801     }
1802
1803     /// An item is 'leaked' from a private dependency if all
1804     /// of the following are true:
1805     /// 1. It's contained within a public type
1806     /// 2. It comes from a private crate
1807     fn leaks_private_dep(&self, item_id: DefId) -> bool {
1808         let ret = self.required_visibility.is_public() && self.tcx.is_private_dep(item_id.krate);
1809
1810         tracing::debug!("leaks_private_dep(item_id={:?})={}", item_id, ret);
1811         ret
1812     }
1813 }
1814
1815 impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
1816     fn tcx(&self) -> TyCtxt<'tcx> {
1817         self.tcx
1818     }
1819     fn visit_def_id(
1820         &mut self,
1821         def_id: DefId,
1822         kind: &str,
1823         descr: &dyn fmt::Display,
1824     ) -> ControlFlow<Self::BreakTy> {
1825         if self.check_def_id(def_id, kind, descr) {
1826             ControlFlow::BREAK
1827         } else {
1828             ControlFlow::CONTINUE
1829         }
1830     }
1831 }
1832
1833 struct PrivateItemsInPublicInterfacesChecker<'tcx> {
1834     tcx: TyCtxt<'tcx>,
1835     old_error_set_ancestry: LocalDefIdSet,
1836 }
1837
1838 impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
1839     fn check(
1840         &self,
1841         def_id: LocalDefId,
1842         required_visibility: ty::Visibility,
1843     ) -> SearchInterfaceForPrivateItemsVisitor<'tcx> {
1844         SearchInterfaceForPrivateItemsVisitor {
1845             tcx: self.tcx,
1846             item_def_id: def_id,
1847             required_visibility,
1848             has_old_errors: self.old_error_set_ancestry.contains(&def_id),
1849             in_assoc_ty: false,
1850         }
1851     }
1852
1853     fn check_assoc_item(
1854         &self,
1855         def_id: LocalDefId,
1856         assoc_item_kind: AssocItemKind,
1857         defaultness: hir::Defaultness,
1858         vis: ty::Visibility,
1859     ) {
1860         let mut check = self.check(def_id, vis);
1861
1862         let (check_ty, is_assoc_ty) = match assoc_item_kind {
1863             AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false),
1864             AssocItemKind::Type => (defaultness.has_value(), true),
1865         };
1866         check.in_assoc_ty = is_assoc_ty;
1867         check.generics().predicates();
1868         if check_ty {
1869             check.ty();
1870         }
1871     }
1872
1873     pub fn check_item(&mut self, id: ItemId) {
1874         let tcx = self.tcx;
1875         let item_visibility = tcx.visibility(id.def_id);
1876         let def_kind = tcx.def_kind(id.def_id);
1877
1878         match def_kind {
1879             DefKind::Const | DefKind::Static(_) | DefKind::Fn | DefKind::TyAlias => {
1880                 self.check(id.def_id, item_visibility).generics().predicates().ty();
1881             }
1882             DefKind::OpaqueTy => {
1883                 // `ty()` for opaque types is the underlying type,
1884                 // it's not a part of interface, so we skip it.
1885                 self.check(id.def_id, item_visibility).generics().bounds();
1886             }
1887             DefKind::Trait => {
1888                 let item = tcx.hir().item(id);
1889                 if let hir::ItemKind::Trait(.., trait_item_refs) = item.kind {
1890                     self.check(item.def_id, item_visibility).generics().predicates();
1891
1892                     for trait_item_ref in trait_item_refs {
1893                         self.check_assoc_item(
1894                             trait_item_ref.id.def_id,
1895                             trait_item_ref.kind,
1896                             trait_item_ref.defaultness,
1897                             item_visibility,
1898                         );
1899
1900                         if let AssocItemKind::Type = trait_item_ref.kind {
1901                             self.check(trait_item_ref.id.def_id, item_visibility).bounds();
1902                         }
1903                     }
1904                 }
1905             }
1906             DefKind::TraitAlias => {
1907                 self.check(id.def_id, item_visibility).generics().predicates();
1908             }
1909             DefKind::Enum => {
1910                 let item = tcx.hir().item(id);
1911                 if let hir::ItemKind::Enum(ref def, _) = item.kind {
1912                     self.check(item.def_id, item_visibility).generics().predicates();
1913
1914                     for variant in def.variants {
1915                         for field in variant.data.fields() {
1916                             self.check(self.tcx.hir().local_def_id(field.hir_id), item_visibility)
1917                                 .ty();
1918                         }
1919                     }
1920                 }
1921             }
1922             // Subitems of foreign modules have their own publicity.
1923             DefKind::ForeignMod => {
1924                 let item = tcx.hir().item(id);
1925                 if let hir::ItemKind::ForeignMod { items, .. } = item.kind {
1926                     for foreign_item in items {
1927                         let vis = tcx.visibility(foreign_item.id.def_id);
1928                         self.check(foreign_item.id.def_id, vis).generics().predicates().ty();
1929                     }
1930                 }
1931             }
1932             // Subitems of structs and unions have their own publicity.
1933             DefKind::Struct | DefKind::Union => {
1934                 let item = tcx.hir().item(id);
1935                 if let hir::ItemKind::Struct(ref struct_def, _)
1936                 | hir::ItemKind::Union(ref struct_def, _) = item.kind
1937                 {
1938                     self.check(item.def_id, item_visibility).generics().predicates();
1939
1940                     for field in struct_def.fields() {
1941                         let def_id = tcx.hir().local_def_id(field.hir_id);
1942                         let field_visibility = tcx.visibility(def_id);
1943                         self.check(def_id, min(item_visibility, field_visibility, tcx)).ty();
1944                     }
1945                 }
1946             }
1947             // An inherent impl is public when its type is public
1948             // Subitems of inherent impls have their own publicity.
1949             // A trait impl is public when both its type and its trait are public
1950             // Subitems of trait impls have inherited publicity.
1951             DefKind::Impl => {
1952                 let item = tcx.hir().item(id);
1953                 if let hir::ItemKind::Impl(ref impl_) = item.kind {
1954                     let impl_vis = ty::Visibility::of_impl(item.def_id, tcx, &Default::default());
1955                     // check that private components do not appear in the generics or predicates of inherent impls
1956                     // this check is intentionally NOT performed for impls of traits, per #90586
1957                     if impl_.of_trait.is_none() {
1958                         self.check(item.def_id, impl_vis).generics().predicates();
1959                     }
1960                     for impl_item_ref in impl_.items {
1961                         let impl_item_vis = if impl_.of_trait.is_none() {
1962                             min(tcx.visibility(impl_item_ref.id.def_id), impl_vis, tcx)
1963                         } else {
1964                             impl_vis
1965                         };
1966                         self.check_assoc_item(
1967                             impl_item_ref.id.def_id,
1968                             impl_item_ref.kind,
1969                             impl_item_ref.defaultness,
1970                             impl_item_vis,
1971                         );
1972                     }
1973                 }
1974             }
1975             _ => {}
1976         }
1977     }
1978 }
1979
1980 pub fn provide(providers: &mut Providers) {
1981     *providers = Providers {
1982         visibility,
1983         privacy_access_levels,
1984         check_private_in_public,
1985         check_mod_privacy,
1986         ..*providers
1987     };
1988 }
1989
1990 fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility {
1991     let def_id = def_id.expect_local();
1992     match tcx.resolutions(()).visibilities.get(&def_id) {
1993         Some(vis) => *vis,
1994         None => {
1995             let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
1996             match tcx.hir().get(hir_id) {
1997                 // Unique types created for closures participate in type privacy checking.
1998                 // They have visibilities inherited from the module they are defined in.
1999                 Node::Expr(hir::Expr { kind: hir::ExprKind::Closure{..}, .. })
2000                 // - AST lowering creates dummy `use` items which don't
2001                 //   get their entries in the resolver's visibility table.
2002                 // - AST lowering also creates opaque type items with inherited visibilities.
2003                 //   Visibility on them should have no effect, but to avoid the visibility
2004                 //   query failing on some items, we provide it for opaque types as well.
2005                 | Node::Item(hir::Item {
2006                     kind: hir::ItemKind::Use(_, hir::UseKind::ListStem) | hir::ItemKind::OpaqueTy(..),
2007                     ..
2008                 }) => ty::Visibility::Restricted(tcx.parent_module(hir_id).to_def_id()),
2009                 // Visibilities of trait impl items are inherited from their traits
2010                 // and are not filled in resolve.
2011                 Node::ImplItem(impl_item) => {
2012                     match tcx.hir().get_by_def_id(tcx.hir().get_parent_item(hir_id)) {
2013                         Node::Item(hir::Item {
2014                             kind: hir::ItemKind::Impl(hir::Impl { of_trait: Some(tr), .. }),
2015                             ..
2016                         }) => tr.path.res.opt_def_id().map_or_else(
2017                             || {
2018                                 tcx.sess.delay_span_bug(tr.path.span, "trait without a def-id");
2019                                 ty::Visibility::Public
2020                             },
2021                             |def_id| tcx.visibility(def_id),
2022                         ),
2023                         _ => span_bug!(impl_item.span, "the parent is not a trait impl"),
2024                     }
2025                 }
2026                 _ => span_bug!(
2027                     tcx.def_span(def_id),
2028                     "visibility table unexpectedly missing a def-id: {:?}",
2029                     def_id,
2030                 ),
2031             }
2032         }
2033     }
2034 }
2035
2036 fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
2037     // Check privacy of names not checked in previous compilation stages.
2038     let mut visitor =
2039         NamePrivacyVisitor { tcx, maybe_typeck_results: None, current_item: module_def_id };
2040     let (module, span, hir_id) = tcx.hir().get_module(module_def_id);
2041
2042     intravisit::walk_mod(&mut visitor, module, hir_id);
2043
2044     // Check privacy of explicitly written types and traits as well as
2045     // inferred types of expressions and patterns.
2046     let mut visitor =
2047         TypePrivacyVisitor { tcx, maybe_typeck_results: None, current_item: module_def_id, span };
2048     intravisit::walk_mod(&mut visitor, module, hir_id);
2049 }
2050
2051 fn privacy_access_levels(tcx: TyCtxt<'_>, (): ()) -> &AccessLevels {
2052     // Build up a set of all exported items in the AST. This is a set of all
2053     // items which are reachable from external crates based on visibility.
2054     let mut visitor = EmbargoVisitor {
2055         tcx,
2056         access_levels: tcx.resolutions(()).access_levels.clone(),
2057         macro_reachable: Default::default(),
2058         prev_level: Some(AccessLevel::Public),
2059         changed: false,
2060     };
2061
2062     loop {
2063         tcx.hir().walk_toplevel_module(&mut visitor);
2064         if visitor.changed {
2065             visitor.changed = false;
2066         } else {
2067             break;
2068         }
2069     }
2070
2071     tcx.arena.alloc(visitor.access_levels)
2072 }
2073
2074 fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
2075     let access_levels = tcx.privacy_access_levels(());
2076
2077     let mut visitor = ObsoleteVisiblePrivateTypesVisitor {
2078         tcx,
2079         access_levels,
2080         in_variant: false,
2081         old_error_set: Default::default(),
2082     };
2083     tcx.hir().walk_toplevel_module(&mut visitor);
2084
2085     let mut old_error_set_ancestry = HirIdSet::default();
2086     for mut id in visitor.old_error_set.iter().copied() {
2087         loop {
2088             if !old_error_set_ancestry.insert(id) {
2089                 break;
2090             }
2091             let parent = tcx.hir().get_parent_node(id);
2092             if parent == id {
2093                 break;
2094             }
2095             id = parent;
2096         }
2097     }
2098
2099     // Check for private types and traits in public interfaces.
2100     let mut checker = PrivateItemsInPublicInterfacesChecker {
2101         tcx,
2102         // Only definition IDs are ever searched in `old_error_set_ancestry`,
2103         // so we can filter away all non-definition IDs at this point.
2104         old_error_set_ancestry: old_error_set_ancestry
2105             .into_iter()
2106             .filter_map(|hir_id| tcx.hir().opt_local_def_id(hir_id))
2107             .collect(),
2108     };
2109
2110     for id in tcx.hir().items() {
2111         checker.check_item(id);
2112     }
2113 }