Skip to content

Commit 0fd5712

Browse files
committed
Auto merge of #123377 - oli-obk:private_projection, r=compiler-errors
Only inspect user-written predicates for privacy concerns fixes #123288 Previously we looked at the elaborated predicates, which, due to adding various bounds on fields, end up requiring trivially true bounds. But these bounds can contain private types, which the privacy visitor then found and errored about.
2 parents 96eaf55 + 83bd12c commit 0fd5712

File tree

2 files changed

+44
-5
lines changed

2 files changed

+44
-5
lines changed

compiler/rustc_ty_utils/src/sig_types.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub trait SpannedTypeVisitor<'tcx> {
1313
fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> Self::Result;
1414
}
1515

16+
#[instrument(level = "trace", skip(tcx, visitor))]
1617
pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
1718
tcx: TyCtxt<'tcx>,
1819
item: LocalDefId,
@@ -36,7 +37,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
3637
for (hir, ty) in hir_sig.inputs.iter().zip(ty_sig.inputs().iter()) {
3738
try_visit!(visitor.visit(hir.span, ty.map_bound(|x| *x)));
3839
}
39-
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
40+
for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
4041
try_visit!(visitor.visit(span, pred));
4142
}
4243
}
@@ -54,7 +55,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
5455
// Associated types in traits don't necessarily have a type that we can visit
5556
try_visit!(visitor.visit(ty.span, tcx.type_of(item).instantiate_identity()));
5657
}
57-
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
58+
for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
5859
try_visit!(visitor.visit(span, pred));
5960
}
6061
}
@@ -76,7 +77,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
7677
let ty = field.ty(tcx, args);
7778
try_visit!(visitor.visit(span, ty));
7879
}
79-
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
80+
for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
8081
try_visit!(visitor.visit(span, pred));
8182
}
8283
}
@@ -95,12 +96,12 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
9596
_ => tcx.def_span(item),
9697
};
9798
try_visit!(visitor.visit(span, tcx.type_of(item).instantiate_identity()));
98-
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
99+
for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
99100
try_visit!(visitor.visit(span, pred));
100101
}
101102
}
102103
DefKind::TraitAlias | DefKind::Trait => {
103-
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
104+
for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
104105
try_visit!(visitor.visit(span, pred));
105106
}
106107
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//! To determine all the types that need to be private when looking at `Struct`, we
2+
//! used to invoke `predicates_of` to also look at types in `where` bounds.
3+
//! Unfortunately this also computes the inferred outlives bounds, which means for
4+
//! every field we check that if it is of type `&'a T` then `T: 'a` and if it is of
5+
//! struct type, we check that the struct satisfies its lifetime parameters by looking
6+
//! at its inferred outlives bounds. This means we end up with a `<Foo as Trait>::Assoc: 'a`
7+
//! in the outlives bounds of `Struct`. While this is trivially provable, privacy
8+
//! only sees `Foo` and `Trait` and determines that `Foo` is private and then errors.
9+
//! So now we invoke `explicit_predicates_of` to make sure we only care about user-written
10+
//! predicates.
11+
12+
//@ check-pass
13+
14+
mod baz {
15+
struct Foo;
16+
17+
pub trait Trait {
18+
type Assoc;
19+
}
20+
21+
impl Trait for Foo {
22+
type Assoc = ();
23+
}
24+
25+
pub struct Bar<'a, T: Trait> {
26+
source: &'a T::Assoc,
27+
}
28+
29+
pub struct Baz<'a> {
30+
mode: Bar<'a, Foo>,
31+
}
32+
}
33+
34+
pub struct Struct<'a> {
35+
lexer: baz::Baz<'a>,
36+
}
37+
38+
fn main() {}

0 commit comments

Comments
 (0)