Skip to content

Commit f8e844a

Browse files
Auto merge of #147486 - petrochenkov:optpriv, r=<try>
[PERF] privacy: Visit DefIds once in DefIdVisitorSkeleton
2 parents acf2437 + 440e11e commit f8e844a

File tree

7 files changed

+32
-63
lines changed

7 files changed

+32
-63
lines changed

compiler/rustc_privacy/src/lib.rs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,16 @@ pub trait DefIdVisitor<'tcx> {
7575
}
7676

7777
fn tcx(&self) -> TyCtxt<'tcx>;
78+
/// NOTE: Def-id visiting should be idempotent, because `DefIdVisitorSkeleton` will avoid
79+
/// visiting duplicate def-ids. All the current visitors follow this rule.
7880
fn visit_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display)
7981
-> Self::Result;
8082

8183
/// Not overridden, but used to actually visit types and traits.
8284
fn skeleton(&mut self) -> DefIdVisitorSkeleton<'_, 'tcx, Self> {
8385
DefIdVisitorSkeleton {
8486
def_id_visitor: self,
85-
visited_opaque_tys: Default::default(),
87+
visited_tys: Default::default(),
8688
dummy: Default::default(),
8789
}
8890
}
@@ -102,7 +104,7 @@ pub trait DefIdVisitor<'tcx> {
102104

103105
pub struct DefIdVisitorSkeleton<'v, 'tcx, V: ?Sized> {
104106
def_id_visitor: &'v mut V,
105-
visited_opaque_tys: FxHashSet<DefId>,
107+
visited_tys: FxHashSet<Ty<'tcx>>,
106108
dummy: PhantomData<TyCtxt<'tcx>>,
107109
}
108110

@@ -180,6 +182,9 @@ where
180182
}
181183

182184
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
185+
if !self.visited_tys.insert(ty) {
186+
return V::Result::output();
187+
}
183188
let tcx = self.def_id_visitor.tcx();
184189
// GenericArgs are not visited here because they are visited below
185190
// in `super_visit_with`.
@@ -258,17 +263,14 @@ where
258263
}
259264
}
260265
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => {
261-
// Skip repeated `Opaque`s to avoid infinite recursion.
262-
if self.visited_opaque_tys.insert(def_id) {
263-
// The intent is to treat `impl Trait1 + Trait2` identically to
264-
// `dyn Trait1 + Trait2`. Therefore we ignore def-id of the opaque type itself
265-
// (it either has no visibility, or its visibility is insignificant, like
266-
// visibilities of type aliases) and recurse into bounds instead to go
267-
// through the trait list (default type visitor doesn't visit those traits).
268-
// All traits in the list are considered the "primary" part of the type
269-
// and are visited by shallow visitors.
270-
try_visit!(self.visit_clauses(tcx.explicit_item_bounds(def_id).skip_binder()));
271-
}
266+
// The intent is to treat `impl Trait1 + Trait2` identically to
267+
// `dyn Trait1 + Trait2`. Therefore we ignore def-id of the opaque type itself
268+
// (it either has no visibility, or its visibility is insignificant, like
269+
// visibilities of type aliases) and recurse into bounds instead to go
270+
// through the trait list (default type visitor doesn't visit those traits).
271+
// All traits in the list are considered the "primary" part of the type
272+
// and are visited by shallow visitors.
273+
try_visit!(self.visit_clauses(tcx.explicit_item_bounds(def_id).skip_binder()));
272274
}
273275
// These types don't have their own def-ids (but may have subcomponents
274276
// with def-ids that should be visited recursively).
@@ -923,7 +925,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
923925

924926
// Checks that a field in a struct constructor (expression or pattern) is accessible.
925927
fn check_field(
926-
&mut self,
928+
&self,
927929
hir_id: hir::HirId, // ID of the field use
928930
use_ctxt: Span, // syntax context of the field name at the use site
929931
def: ty::AdtDef<'tcx>, // definition of the struct or enum
@@ -941,7 +943,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
941943

942944
// Checks that a field in a struct constructor (expression or pattern) is accessible.
943945
fn emit_unreachable_field_error(
944-
&mut self,
946+
&self,
945947
fields: Vec<(Symbol, Span, bool /* field is present */)>,
946948
def: ty::AdtDef<'tcx>, // definition of the struct or enum
947949
update_syntax: Option<Span>,
@@ -1004,7 +1006,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
10041006
}
10051007

10061008
fn check_expanded_fields(
1007-
&mut self,
1009+
&self,
10081010
adt: ty::AdtDef<'tcx>,
10091011
variant: &'tcx ty::VariantDef,
10101012
fields: &[hir::ExprField<'tcx>],
@@ -1142,7 +1144,7 @@ impl<'tcx> TypePrivacyVisitor<'tcx> {
11421144
result.is_break()
11431145
}
11441146

1145-
fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool {
1147+
fn check_def_id(&self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool {
11461148
let is_error = !self.item_is_accessible(def_id);
11471149
if is_error {
11481150
self.tcx.dcx().emit_err(ItemIsPrivate { span: self.span, kind, descr: descr.into() });
@@ -1401,7 +1403,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
14011403
self
14021404
}
14031405

1404-
fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool {
1406+
fn check_def_id(&self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool {
14051407
if self.leaks_private_dep(def_id) {
14061408
self.tcx.emit_node_span_lint(
14071409
lint::builtin::EXPORTED_PRIVATE_DEPENDENCIES,

tests/ui/const-generics/generic_const_exprs/eval-privacy.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ where
1616
{
1717
type AssocTy = Const<{ my_const_fn(U) }>;
1818
//~^ ERROR private type
19-
//~| ERROR private type
2019
fn assoc_fn() -> Self::AssocTy {
2120
Const
2221
}

tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,6 @@ LL | type AssocTy = Const<{ my_const_fn(U) }>;
77
LL | const fn my_const_fn(val: u8) -> u8 {
88
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
99

10-
error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
11-
--> $DIR/eval-privacy.rs:17:5
12-
|
13-
LL | type AssocTy = Const<{ my_const_fn(U) }>;
14-
| ^^^^^^^^^^^^ can't leak private type
15-
...
16-
LL | const fn my_const_fn(val: u8) -> u8 {
17-
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
18-
|
19-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
20-
21-
error: aborting due to 2 previous errors
10+
error: aborting due to 1 previous error
2211

2312
For more information about this error, try `rustc --explain E0446`.

tests/ui/privacy/pub-priv-dep/pub-priv1.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ impl From<PublicWithStdImpl> for OtherType {
145145
//~| ERROR type `OtherType` from private dependency 'priv_dep' in public interface
146146
fn from(val: PublicWithStdImpl) -> Self { Self }
147147
//~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface
148-
//~| ERROR type `OtherType` from private dependency 'priv_dep' in public interface
149148
}
150149

151150
pub struct AllowedPrivType {

tests/ui/privacy/pub-priv-dep/pub-priv1.stderr

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,55 +11,55 @@ LL | #![deny(exported_private_dependencies)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212

1313
error: macro `m` from private dependency 'priv_dep' is re-exported
14-
--> $DIR/pub-priv1.rs:156:9
14+
--> $DIR/pub-priv1.rs:155:9
1515
|
1616
LL | pub use priv_dep::m;
1717
| ^^^^^^^^^^^
1818

1919
error: macro `fn_like` from private dependency 'pm' is re-exported
20-
--> $DIR/pub-priv1.rs:158:9
20+
--> $DIR/pub-priv1.rs:157:9
2121
|
2222
LL | pub use pm::fn_like;
2323
| ^^^^^^^^^^^
2424

2525
error: derive macro `PmDerive` from private dependency 'pm' is re-exported
26-
--> $DIR/pub-priv1.rs:160:9
26+
--> $DIR/pub-priv1.rs:159:9
2727
|
2828
LL | pub use pm::PmDerive;
2929
| ^^^^^^^^^^^^
3030

3131
error: attribute macro `pm_attr` from private dependency 'pm' is re-exported
32-
--> $DIR/pub-priv1.rs:162:9
32+
--> $DIR/pub-priv1.rs:161:9
3333
|
3434
LL | pub use pm::pm_attr;
3535
| ^^^^^^^^^^^
3636

3737
error: variant `V1` from private dependency 'priv_dep' is re-exported
38-
--> $DIR/pub-priv1.rs:165:9
38+
--> $DIR/pub-priv1.rs:164:9
3939
|
4040
LL | pub use priv_dep::E::V1;
4141
| ^^^^^^^^^^^^^^^
4242

4343
error: type alias `Unit` from private dependency 'priv_dep' is re-exported
44-
--> $DIR/pub-priv1.rs:168:9
44+
--> $DIR/pub-priv1.rs:167:9
4545
|
4646
LL | pub use priv_dep::Unit;
4747
| ^^^^^^^^^^^^^^
4848

4949
error: type alias `PubPub` from private dependency 'priv_dep' is re-exported
50-
--> $DIR/pub-priv1.rs:170:9
50+
--> $DIR/pub-priv1.rs:169:9
5151
|
5252
LL | pub use priv_dep::PubPub;
5353
| ^^^^^^^^^^^^^^^^
5454

5555
error: type alias `PubPriv` from private dependency 'priv_dep' is re-exported
56-
--> $DIR/pub-priv1.rs:172:9
56+
--> $DIR/pub-priv1.rs:171:9
5757
|
5858
LL | pub use priv_dep::PubPriv;
5959
| ^^^^^^^^^^^^^^^^^
6060

6161
error: struct `Renamed` from private dependency 'priv_dep' is re-exported
62-
--> $DIR/pub-priv1.rs:174:9
62+
--> $DIR/pub-priv1.rs:173:9
6363
|
6464
LL | pub use priv_dep::OtherType as Renamed;
6565
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -248,13 +248,5 @@ error: type `OtherType` from private dependency 'priv_dep' in public interface
248248
LL | fn from(val: PublicWithStdImpl) -> Self { Self }
249249
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
250250

251-
error: type `OtherType` from private dependency 'priv_dep' in public interface
252-
--> $DIR/pub-priv1.rs:146:5
253-
|
254-
LL | fn from(val: PublicWithStdImpl) -> Self { Self }
255-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
256-
|
257-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
258-
259-
error: aborting due to 41 previous errors
251+
error: aborting due to 40 previous errors
260252

tests/ui/privacy/where-priv-type.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ where
6565
{
6666
type AssocTy = Const<{ my_const_fn(U) }>;
6767
//~^ ERROR private type
68-
//~| ERROR private type
6968
fn assoc_fn() -> Self::AssocTy {
7069
Const
7170
}

tests/ui/privacy/where-priv-type.stderr

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,6 @@ LL | type AssocTy = Const<{ my_const_fn(U) }>;
7777
LL | const fn my_const_fn(val: u8) -> u8 {
7878
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
7979

80-
error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
81-
--> $DIR/where-priv-type.rs:66:5
82-
|
83-
LL | type AssocTy = Const<{ my_const_fn(U) }>;
84-
| ^^^^^^^^^^^^ can't leak private type
85-
...
86-
LL | const fn my_const_fn(val: u8) -> u8 {
87-
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
88-
|
89-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
90-
91-
error: aborting due to 2 previous errors; 5 warnings emitted
80+
error: aborting due to 1 previous error; 5 warnings emitted
9281

9382
For more information about this error, try `rustc --explain E0446`.

0 commit comments

Comments
 (0)