Skip to content

Commit

Permalink
Only inspect user-written predicates for privacy concerns
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Apr 4, 2024
1 parent 769ab55 commit fd2f6fc
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 15 deletions.
11 changes: 6 additions & 5 deletions compiler/rustc_ty_utils/src/sig_types.rs
Expand Up @@ -13,6 +13,7 @@ pub trait SpannedTypeVisitor<'tcx> {
fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> Self::Result;
}

#[instrument(level = "trace", skip(tcx, visitor))]
pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
tcx: TyCtxt<'tcx>,
item: LocalDefId,
Expand All @@ -36,7 +37,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
for (hir, ty) in hir_sig.inputs.iter().zip(ty_sig.inputs().iter()) {
try_visit!(visitor.visit(hir.span, ty.map_bound(|x| *x)));
}
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
try_visit!(visitor.visit(span, pred));
}
}
Expand All @@ -54,7 +55,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
// Associated types in traits don't necessarily have a type that we can visit
try_visit!(visitor.visit(ty.span, tcx.type_of(item).instantiate_identity()));
}
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
try_visit!(visitor.visit(span, pred));
}
}
Expand All @@ -76,7 +77,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
let ty = field.ty(tcx, args);
try_visit!(visitor.visit(span, ty));
}
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
try_visit!(visitor.visit(span, pred));
}
}
Expand All @@ -95,12 +96,12 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
_ => tcx.def_span(item),
};
try_visit!(visitor.visit(span, tcx.type_of(item).instantiate_identity()));
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
try_visit!(visitor.visit(span, pred));
}
}
DefKind::TraitAlias | DefKind::Trait => {
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
try_visit!(visitor.visit(span, pred));
}
}
Expand Down
7 changes: 5 additions & 2 deletions tests/ui/privacy/generic_struct_field_projection.rs
@@ -1,11 +1,15 @@
//! To determine all the types that need to be private when looking at `Struct`, we
//! invoke `predicates_of` to also look at types in `where` bounds.
//! used to invoke `predicates_of` to also look at types in `where` bounds.
//! Unfortunately this also computes the inferred outlives bounds, which means for
//! every field we check that if it is of type `&'a T` then `T: 'a` and if it is of
//! struct type, we check that the struct satisfies its lifetime parameters by looking
//! at its inferred outlives bounds. This means we end up with a `<Foo as Trait>::Assoc: 'a`
//! in the outlives bounds of `Struct`. While this is trivially provable, privacy
//! only sees `Foo` and `Trait` and determins that `Foo` is private and then errors.
//! So now we invoke `explicit_predicates_of` to make sure we only care about user-written
//! predicates.

//@ check-pass

mod baz {
struct Foo;
Expand All @@ -20,7 +24,6 @@ mod baz {

pub struct Bar<'a, T: Trait> {
source: &'a T::Assoc,
//~^ ERROR: type `Foo` is private
}

pub struct Baz<'a> {
Expand Down
8 changes: 0 additions & 8 deletions tests/ui/privacy/generic_struct_field_projection.stderr

This file was deleted.

0 comments on commit fd2f6fc

Please sign in to comment.