Skip to content

Commit 3945ced

Browse files
committed
Use relative visibility when noting sealed trait to reduce false positive
Signed-off-by: xizheyin <[email protected]>
1 parent 2111525 commit 3945ced

File tree

3 files changed

+17
-8
lines changed

3 files changed

+17
-8
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::query::Key;
2526
use rustc_middle::traits::IsConstable;
2627
use rustc_middle::ty::error::TypeError;
2728
use rustc_middle::ty::print::{
@@ -2775,11 +2776,20 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
27752776
ty::ClauseKind::Trait(trait_pred) => {
27762777
let def_id = trait_pred.def_id();
27772778
let visible_item = if let Some(local) = def_id.as_local() {
2778-
// Check for local traits being reachable.
2779-
let vis = &tcx.resolutions(()).effective_visibilities;
2780-
// Account for non-`pub` traits in the root of the local crate.
2781-
let is_locally_reachable = tcx.parent(def_id).is_crate_root();
2782-
vis.is_reachable(local) || is_locally_reachable
2779+
let ty = trait_pred.self_ty();
2780+
if let Some(id) = ty.def_id_for_ty_in_cycle() {
2781+
let is_locally_reachable = tcx.parent(def_id).is_crate_root();
2782+
let vis: &rustc_middle::middle::privacy::EffectiveVisibilities =
2783+
&tcx.resolutions(()).effective_visibilities;
2784+
let is_reachable = vis.effective_vis(local).is_some_and(|v| {
2785+
v.at_level(rustc_middle::middle::privacy::Level::Reachable)
2786+
.is_accessible_from(id, tcx)
2787+
});
2788+
is_reachable || is_locally_reachable
2789+
} else {
2790+
// FIXME(xizheyin): if the type is not ADT, we should not suggest it
2791+
true
2792+
}
27832793
} else {
27842794
// Check for foreign traits being reachable.
27852795
tcx.visible_parent_map(()).get(&def_id).is_some()

tests/ui/privacy/sealed-traits/false-sealed-traits-note.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// when we impl TraitA for Struct, it can compile, we should not emit sealed traits note, see issue #143392
1+
// We should not emit sealed traits note, see issue #143392
22

33
mod inner {
44
pub trait TraitA {}
@@ -10,4 +10,4 @@ struct Struct;
1010

1111
impl inner::TraitB for Struct {} //~ ERROR the trait bound `Struct: TraitA` is not satisfied [E0277]
1212

13-
fn main(){}
13+
fn main(){}

tests/ui/privacy/sealed-traits/false-sealed-traits-note.stderr

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ note: required by a bound in `TraitB`
1414
|
1515
LL | pub trait TraitB: TraitA {}
1616
| ^^^^^^ required by this bound in `TraitB`
17-
= note: `TraitB` is a "sealed trait", because to implement it you also need to implement `inner::TraitA`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it
1817

1918
error: aborting due to 1 previous error
2019

0 commit comments

Comments
 (0)