Skip to content

Commit 2fabfbc

Browse files
authored
Unrolled build for rust-lang#116945
Rollup merge of rust-lang#116945 - estebank:sealed-trait-impls, r=petrochenkov When encountering sealed traits, point types that implement it ``` error[E0277]: the trait bound `S: d::Hidden` is not satisfied --> $DIR/sealed-trait-local.rs:53:20 | LL | impl c::Sealed for S {} | ^ the trait `d::Hidden` is not implemented for `S` | note: required by a bound in `c::Sealed` --> $DIR/sealed-trait-local.rs:17:23 | LL | pub trait Sealed: self::d::Hidden { | ^^^^^^^^^^^^^^^ required by this bound in `Sealed` = note: `Sealed` is a "sealed trait", because to implement it you also need to implement `c::d::Hidden`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it = help: the following types implement the trait: - c::X - c::Y ``` The last `help` is new.
2 parents 17659c7 + 6dbad23 commit 2fabfbc

File tree

3 files changed

+105
-9
lines changed

3 files changed

+105
-9
lines changed

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

+28-2
Original file line numberDiff line numberDiff line change
@@ -2691,15 +2691,41 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
26912691
if let DefKind::Trait = tcx.def_kind(item_def_id)
26922692
&& !visible_item
26932693
{
2694-
// FIXME(estebank): extend this to search for all the types that do
2695-
// implement this trait and list them.
26962694
err.note(format!(
26972695
"`{short_item_name}` is a \"sealed trait\", because to implement \
26982696
it you also need to implement `{}`, which is not accessible; \
26992697
this is usually done to force you to use one of the provided \
27002698
types that already implement it",
27012699
with_no_trimmed_paths!(tcx.def_path_str(def_id)),
27022700
));
2701+
let impls_of = tcx.trait_impls_of(def_id);
2702+
let impls = impls_of
2703+
.non_blanket_impls()
2704+
.values()
2705+
.flatten()
2706+
.chain(impls_of.blanket_impls().iter())
2707+
.collect::<Vec<_>>();
2708+
if !impls.is_empty() {
2709+
let len = impls.len();
2710+
let mut types = impls.iter()
2711+
.map(|t| with_no_trimmed_paths!(format!(
2712+
" {}",
2713+
tcx.type_of(*t).instantiate_identity(),
2714+
)))
2715+
.collect::<Vec<_>>();
2716+
let post = if types.len() > 9 {
2717+
types.truncate(8);
2718+
format!("\nand {} others", len - 8)
2719+
} else {
2720+
String::new()
2721+
};
2722+
err.help(format!(
2723+
"the following type{} implement{} the trait:\n{}{post}",
2724+
pluralize!(len),
2725+
if len == 1 { "s" } else { "" },
2726+
types.join("\n"),
2727+
));
2728+
}
27032729
}
27042730
}
27052731
} else {

tests/ui/privacy/sealed-traits/sealed-trait-local.rs

+38-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,43 @@ pub mod a {
1313
}
1414
}
1515

16-
struct S;
17-
impl a::Sealed for S {} //~ ERROR the trait bound `S: Hidden` is not satisfied
16+
pub mod c {
17+
pub trait Sealed: self::d::Hidden {
18+
fn foo() {}
19+
}
20+
21+
struct X;
22+
impl Sealed for X {}
23+
impl self::d::Hidden for X {}
24+
25+
struct Y;
26+
impl Sealed for Y {}
27+
impl self::d::Hidden for Y {}
28+
29+
mod d {
30+
pub trait Hidden {}
31+
}
32+
}
1833

34+
pub mod e {
35+
pub trait Sealed: self::f::Hidden {
36+
fn foo() {}
37+
}
38+
39+
struct X;
40+
impl self::f::Hidden for X {}
41+
42+
struct Y;
43+
impl self::f::Hidden for Y {}
44+
impl<T: self::f::Hidden> Sealed for T {}
45+
46+
mod f {
47+
pub trait Hidden {}
48+
}
49+
}
50+
51+
struct S;
52+
impl a::Sealed for S {} //~ ERROR the trait bound
53+
impl c::Sealed for S {} //~ ERROR the trait bound
54+
impl e::Sealed for S {} //~ ERROR the trait bound
1955
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,50 @@
1-
error[E0277]: the trait bound `S: Hidden` is not satisfied
2-
--> $DIR/sealed-trait-local.rs:17:20
1+
error[E0277]: the trait bound `S: b::Hidden` is not satisfied
2+
--> $DIR/sealed-trait-local.rs:52:20
33
|
44
LL | impl a::Sealed for S {}
5-
| ^ the trait `Hidden` is not implemented for `S`
5+
| ^ the trait `b::Hidden` is not implemented for `S`
66
|
7-
note: required by a bound in `Sealed`
7+
note: required by a bound in `a::Sealed`
88
--> $DIR/sealed-trait-local.rs:3:23
99
|
1010
LL | pub trait Sealed: self::b::Hidden {
1111
| ^^^^^^^^^^^^^^^ required by this bound in `Sealed`
1212
= note: `Sealed` is a "sealed trait", because to implement it you also need to implement `a::b::Hidden`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it
13+
= help: the following type implements the trait:
14+
a::X
1315

14-
error: aborting due to previous error
16+
error[E0277]: the trait bound `S: d::Hidden` is not satisfied
17+
--> $DIR/sealed-trait-local.rs:53:20
18+
|
19+
LL | impl c::Sealed for S {}
20+
| ^ the trait `d::Hidden` is not implemented for `S`
21+
|
22+
note: required by a bound in `c::Sealed`
23+
--> $DIR/sealed-trait-local.rs:17:23
24+
|
25+
LL | pub trait Sealed: self::d::Hidden {
26+
| ^^^^^^^^^^^^^^^ required by this bound in `Sealed`
27+
= note: `Sealed` is a "sealed trait", because to implement it you also need to implement `c::d::Hidden`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it
28+
= help: the following types implement the trait:
29+
c::X
30+
c::Y
31+
32+
error[E0277]: the trait bound `S: f::Hidden` is not satisfied
33+
--> $DIR/sealed-trait-local.rs:54:20
34+
|
35+
LL | impl e::Sealed for S {}
36+
| ^ the trait `f::Hidden` is not implemented for `S`
37+
|
38+
note: required by a bound in `e::Sealed`
39+
--> $DIR/sealed-trait-local.rs:35:23
40+
|
41+
LL | pub trait Sealed: self::f::Hidden {
42+
| ^^^^^^^^^^^^^^^ required by this bound in `Sealed`
43+
= note: `Sealed` is a "sealed trait", because to implement it you also need to implement `e::f::Hidden`, which is not accessible; this is usually done to force you to use one of the provided types that already implement it
44+
= help: the following types implement the trait:
45+
e::X
46+
e::Y
47+
48+
error: aborting due to 3 previous errors
1549

1650
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)