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