Skip to content

Commit 14b6ac4

Browse files
authored
Rollup merge of rust-lang#143431 - xizheyin:143392, r=compiler-errors
Use relative visibility when noting sealed trait to reduce false positive Fixes rust-lang#143392 I used relative visibility instead of just determining if it's public or not. r? compiler
2 parents 08fa971 + 4a261a1 commit 14b6ac4

File tree

3 files changed

+48
-5
lines changed

3 files changed

+48
-5
lines changed

compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc_hir::{
2222
expr_needs_parens, is_range_literal,
2323
};
2424
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk};
25+
use rustc_middle::middle::privacy::Level;
2526
use rustc_middle::traits::IsConstable;
2627
use rustc_middle::ty::error::TypeError;
2728
use rustc_middle::ty::print::{
@@ -2870,11 +2871,20 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
28702871
ty::ClauseKind::Trait(trait_pred) => {
28712872
let def_id = trait_pred.def_id();
28722873
let visible_item = if let Some(local) = def_id.as_local() {
2873-
// Check for local traits being reachable.
2874-
let vis = &tcx.resolutions(()).effective_visibilities;
2875-
// Account for non-`pub` traits in the root of the local crate.
2876-
let is_locally_reachable = tcx.parent(def_id).is_crate_root();
2877-
vis.is_reachable(local) || is_locally_reachable
2874+
let ty = trait_pred.self_ty();
2875+
// when `TraitA: TraitB` and `S` only impl TraitA,
2876+
// we check if `TraitB` can be reachable from `S`
2877+
// to determine whether to note `TraitA` is sealed trait.
2878+
if let ty::Adt(adt, _) = ty.kind() {
2879+
let visibilities = tcx.effective_visibilities(());
2880+
visibilities.effective_vis(local).is_none_or(|v| {
2881+
v.at_level(Level::Reexported)
2882+
.is_accessible_from(adt.did(), tcx)
2883+
})
2884+
} else {
2885+
// FIXME(xizheyin): if the type is not ADT, we should not suggest it
2886+
true
2887+
}
28782888
} else {
28792889
// Check for foreign traits being reachable.
28802890
tcx.visible_parent_map(()).get(&def_id).is_some()
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// We should not emit sealed traits note, see issue #143392
2+
3+
mod inner {
4+
pub trait TraitA {}
5+
6+
pub trait TraitB: TraitA {}
7+
}
8+
9+
struct Struct;
10+
11+
impl inner::TraitB for Struct {} //~ ERROR the trait bound `Struct: TraitA` is not satisfied [E0277]
12+
13+
fn main(){}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0277]: the trait bound `Struct: TraitA` is not satisfied
2+
--> $DIR/false-sealed-traits-note.rs:11:24
3+
|
4+
LL | impl inner::TraitB for Struct {}
5+
| ^^^^^^ the trait `TraitA` is not implemented for `Struct`
6+
|
7+
help: this trait has no implementations, consider adding one
8+
--> $DIR/false-sealed-traits-note.rs:4:5
9+
|
10+
LL | pub trait TraitA {}
11+
| ^^^^^^^^^^^^^^^^
12+
note: required by a bound in `TraitB`
13+
--> $DIR/false-sealed-traits-note.rs:6:23
14+
|
15+
LL | pub trait TraitB: TraitA {}
16+
| ^^^^^^ required by this bound in `TraitB`
17+
18+
error: aborting due to 1 previous error
19+
20+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)