Skip to content

Commit 419069d

Browse files
committed
Use recorded types in rustc_privacy
1 parent 505ff71 commit 419069d

File tree

6 files changed

+43
-121
lines changed

6 files changed

+43
-121
lines changed

src/Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/librustc_privacy/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ crate-type = ["dylib"]
1010

1111
[dependencies]
1212
rustc = { path = "../librustc" }
13+
rustc_typeck = { path = "../librustc_typeck" }
1314
syntax = { path = "../libsyntax" }
1415
syntax_pos = { path = "../libsyntax_pos" }

src/librustc_privacy/lib.rs

+37-118
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#[macro_use] extern crate rustc;
1919
#[macro_use] extern crate syntax;
20+
extern crate rustc_typeck;
2021
extern crate syntax_pos;
2122

2223
use rustc::hir::{self, PatKind};
@@ -658,65 +659,6 @@ impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> {
658659
}
659660
false
660661
}
661-
662-
fn check_item(&mut self, item_id: ast::NodeId) -> &mut Self {
663-
self.current_item = self.tcx.hir.local_def_id(item_id);
664-
self.span = self.tcx.hir.span(item_id);
665-
self
666-
}
667-
668-
// Convenience methods for checking item interfaces
669-
fn ty(&mut self) -> &mut Self {
670-
self.tcx.type_of(self.current_item).visit_with(self);
671-
self
672-
}
673-
674-
fn generics(&mut self) -> &mut Self {
675-
for def in &self.tcx.generics_of(self.current_item).types {
676-
if def.has_default {
677-
self.tcx.type_of(def.def_id).visit_with(self);
678-
}
679-
}
680-
self
681-
}
682-
683-
fn predicates(&mut self) -> &mut Self {
684-
let predicates = self.tcx.predicates_of(self.current_item);
685-
for predicate in &predicates.predicates {
686-
predicate.visit_with(self);
687-
match predicate {
688-
&ty::Predicate::Trait(poly_predicate) => {
689-
self.check_trait_ref(poly_predicate.skip_binder().trait_ref);
690-
},
691-
&ty::Predicate::Projection(poly_predicate) => {
692-
let tcx = self.tcx;
693-
self.check_trait_ref(
694-
poly_predicate.skip_binder().projection_ty.trait_ref(tcx)
695-
);
696-
},
697-
_ => (),
698-
};
699-
}
700-
self
701-
}
702-
703-
fn impl_trait_ref(&mut self) -> &mut Self {
704-
if let Some(impl_trait_ref) = self.tcx.impl_trait_ref(self.current_item) {
705-
self.check_trait_ref(impl_trait_ref);
706-
}
707-
self.tcx.predicates_of(self.current_item).visit_with(self);
708-
self
709-
}
710-
711-
fn check_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>) -> bool {
712-
if !self.item_is_accessible(trait_ref.def_id) {
713-
let msg = format!("trait `{}` is private", trait_ref);
714-
self.tcx.sess.span_err(self.span, &msg);
715-
return true;
716-
}
717-
718-
trait_ref.super_visit_with(self)
719-
}
720662
}
721663

722664
impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
@@ -733,6 +675,35 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
733675
self.tables = orig_tables;
734676
}
735677

678+
fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty) {
679+
self.span = hir_ty.span;
680+
if let Some(ty) = self.tables.node_id_to_type_opt(hir_ty.hir_id) {
681+
// Types in bodies.
682+
if ty.visit_with(self) {
683+
return;
684+
}
685+
} else {
686+
// Types in signatures.
687+
// FIXME: This is very ineffective. Ideally each HIR type should be converted
688+
// into a semantic type only once and the result should be cached somehow.
689+
if rustc_typeck::hir_ty_to_ty(self.tcx, hir_ty).visit_with(self) {
690+
return;
691+
}
692+
}
693+
694+
intravisit::walk_ty(self, hir_ty);
695+
}
696+
697+
fn visit_trait_ref(&mut self, trait_ref: &'tcx hir::TraitRef) {
698+
if !self.item_is_accessible(trait_ref.path.def.def_id()) {
699+
let msg = format!("trait `{:?}` is private", trait_ref.path);
700+
self.tcx.sess.span_err(self.span, &msg);
701+
return;
702+
}
703+
704+
intravisit::walk_trait_ref(self, trait_ref);
705+
}
706+
736707
// Check types of expressions
737708
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
738709
if self.check_expr_pat_type(expr.hir_id, expr.span) {
@@ -807,63 +778,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
807778
item.id,
808779
&mut self.tables,
809780
self.empty_tables);
810-
811-
match item.node {
812-
hir::ItemExternCrate(..) | hir::ItemMod(..) |
813-
hir::ItemUse(..) | hir::ItemGlobalAsm(..) => {}
814-
hir::ItemConst(..) | hir::ItemStatic(..) |
815-
hir::ItemTy(..) | hir::ItemFn(..) => {
816-
self.check_item(item.id).generics().predicates().ty();
817-
}
818-
hir::ItemTrait(.., ref trait_item_refs) => {
819-
self.check_item(item.id).generics().predicates();
820-
for trait_item_ref in trait_item_refs {
821-
let check = self.check_item(trait_item_ref.id.node_id);
822-
check.generics().predicates();
823-
if trait_item_ref.kind != hir::AssociatedItemKind::Type ||
824-
trait_item_ref.defaultness.has_value() {
825-
check.ty();
826-
}
827-
}
828-
}
829-
hir::ItemEnum(ref def, _) => {
830-
self.check_item(item.id).generics().predicates();
831-
for variant in &def.variants {
832-
for field in variant.node.data.fields() {
833-
self.check_item(field.id).ty();
834-
}
835-
}
836-
}
837-
hir::ItemForeignMod(ref foreign_mod) => {
838-
for foreign_item in &foreign_mod.items {
839-
self.check_item(foreign_item.id).generics().predicates().ty();
840-
}
841-
}
842-
hir::ItemStruct(ref struct_def, _) |
843-
hir::ItemUnion(ref struct_def, _) => {
844-
self.check_item(item.id).generics().predicates();
845-
for field in struct_def.fields() {
846-
self.check_item(field.id).ty();
847-
}
848-
}
849-
hir::ItemDefaultImpl(..) => {
850-
self.check_item(item.id).impl_trait_ref();
851-
}
852-
hir::ItemImpl(.., ref trait_ref, _, ref impl_item_refs) => {
853-
{
854-
let check = self.check_item(item.id);
855-
check.ty().generics().predicates();
856-
if trait_ref.is_some() {
857-
check.impl_trait_ref();
858-
}
859-
}
860-
for impl_item_ref in impl_item_refs {
861-
let impl_item = self.tcx.hir.impl_item(impl_item_ref.id);
862-
self.check_item(impl_item.id).generics().predicates().ty();
863-
}
864-
}
865-
}
866-
867781
self.current_item = self.tcx.hir.local_def_id(item.id);
868782
intravisit::walk_item(self, item);
869783
self.tables = orig_tables;
@@ -924,8 +838,13 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
924838
}
925839
}
926840
ty::TyProjection(ref proj) => {
927-
let tcx = self.tcx;
928-
if self.check_trait_ref(proj.trait_ref(tcx)) {
841+
let trait_ref = proj.trait_ref(self.tcx);
842+
if !self.item_is_accessible(trait_ref.def_id) {
843+
let msg = format!("trait `{}` is private", trait_ref);
844+
self.tcx.sess.span_err(self.span, &msg);
845+
return true;
846+
}
847+
if trait_ref.super_visit_with(self) {
929848
return true;
930849
}
931850
}

src/test/compile-fail/lint-stability-deprecated.rs

+1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ mod cross_crate {
107107
struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable);
108108
struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated);
109109
//~^ WARN use of deprecated item
110+
//~| WARN use of deprecated item
110111

111112
let _ = DeprecatedStruct { //~ WARN use of deprecated item
112113
i: 0 //~ WARN use of deprecated item

src/test/compile-fail/private-inferred-type.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,11 @@ mod adjust {
103103

104104
fn main() {
105105
let _: m::Alias; //~ ERROR type `m::Priv` is private
106-
let _: <m::Alias as m::TraitWithAssocTy>::AssocTy; // FIXME
106+
//~^ ERROR type `m::Priv` is private
107+
let _: <m::Alias as m::TraitWithAssocTy>::AssocTy; //~ ERROR type `m::Priv` is private
107108
m::Alias {}; //~ ERROR type `m::Priv` is private
108109
m::Pub { 0: m::Alias {} }; //~ ERROR type `m::Priv` is private
109-
m::Pub { 0: loop {} }; // FIXME
110+
m::Pub { 0: loop {} }; // OK, `m::Pub` is in value context, so it means Pub<_>, not Pub<Priv>
110111
m::Pub::static_method; //~ ERROR type `m::Priv` is private
111112
m::Pub::INHERENT_ASSOC_CONST; //~ ERROR type `m::Priv` is private
112113
m::Pub(0u8).method_with_substs::<m::Alias>(); //~ ERROR type `m::Priv` is private

src/test/compile-fail/private-type-in-interface.rs

-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ fn f_ext(_: ext::Alias) {} //~ ERROR type `ext::Priv` is private
3131
trait Tr1 {}
3232
impl m::Alias {} //~ ERROR type `m::Priv` is private
3333
impl Tr1 for ext::Alias {} //~ ERROR type `ext::Priv` is private
34-
//~^ ERROR type `ext::Priv` is private
3534
type A = <m::Alias as m::Trait>::X; //~ ERROR type `m::Priv` is private
3635

3736
trait Tr2<T> {}

0 commit comments

Comments
 (0)