Skip to content

Commit b1a2cb2

Browse files
Jules-Bertholetcuviper
authored andcommitted
Handle cycles when checking impl candidates for doc(hidden)
Fixes #149092 (cherry picked from commit f580357)
1 parent 73018d7 commit b1a2cb2

File tree

5 files changed

+37
-5
lines changed

5 files changed

+37
-5
lines changed

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use core::ops::ControlFlow;
22
use std::borrow::Cow;
3+
use std::collections::hash_set;
34
use std::path::PathBuf;
45

56
use rustc_abi::ExternAbi;
67
use rustc_ast::ast::LitKind;
78
use rustc_ast::{LitIntType, TraitObjectSyntax};
8-
use rustc_data_structures::fx::FxHashMap;
9+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
910
use rustc_data_structures::unord::UnordSet;
1011
use rustc_errors::codes::*;
1112
use rustc_errors::{
@@ -1927,11 +1928,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
19271928
if self.tcx.visibility(did).is_accessible_from(body_def_id, self.tcx) {
19281929
// don't suggest foreign `#[doc(hidden)]` types
19291930
if !did.is_local() {
1930-
while let Some(parent) = parent_map.get(&did) {
1931+
let mut previously_seen_dids: FxHashSet<DefId> = Default::default();
1932+
previously_seen_dids.insert(did);
1933+
while let Some(&parent) = parent_map.get(&did)
1934+
&& let hash_set::Entry::Vacant(v) =
1935+
previously_seen_dids.entry(parent)
1936+
{
19311937
if self.tcx.is_doc_hidden(did) {
19321938
return false;
19331939
}
1934-
did = *parent;
1940+
v.insert();
1941+
did = parent;
19351942
}
19361943
}
19371944
true

compiler/rustc_trait_selection/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#![feature(associated_type_defaults)]
2121
#![feature(box_patterns)]
2222
#![feature(default_field_values)]
23+
#![feature(hash_set_entry)]
2324
#![feature(if_let_guard)]
2425
#![feature(iter_intersperse)]
2526
#![feature(iterator_try_reduce)]

tests/ui/suggestions/auxiliary/hidden-struct.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,6 @@ impl Marker for hidden::Foo {}
3333
impl Marker for hidden1::Bar {}
3434
impl Marker for Baz {}
3535
impl Marker for Quux {}
36+
37+
38+
pub use crate as library;

tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@ pub fn test4(_: Quux) {}
2121

2222
fn test5<T: hidden_struct::Marker>() {}
2323

24+
fn test6<T: hidden_struct::library::Marker>() {}
25+
2426
fn main() {
2527
test5::<i32>();
2628
//~^ ERROR [E0277]
29+
30+
test6::<i32>();
31+
//~^ ERROR [E0277]
2732
}

tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ LL + use hidden_struct::Quux;
3838
|
3939

4040
error[E0277]: the trait bound `i32: Marker` is not satisfied
41-
--> $DIR/dont-suggest-foreign-doc-hidden.rs:25:13
41+
--> $DIR/dont-suggest-foreign-doc-hidden.rs:27:13
4242
|
4343
LL | test5::<i32>();
4444
| ^^^ the trait `Marker` is not implemented for `i32`
@@ -53,7 +53,23 @@ note: required by a bound in `test5`
5353
LL | fn test5<T: hidden_struct::Marker>() {}
5454
| ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test5`
5555

56-
error: aborting due to 5 previous errors
56+
error[E0277]: the trait bound `i32: Marker` is not satisfied
57+
--> $DIR/dont-suggest-foreign-doc-hidden.rs:30:13
58+
|
59+
LL | test6::<i32>();
60+
| ^^^ the trait `Marker` is not implemented for `i32`
61+
|
62+
= help: the following other types implement trait `Marker`:
63+
Baz
64+
Option<u32>
65+
Quux
66+
note: required by a bound in `test6`
67+
--> $DIR/dont-suggest-foreign-doc-hidden.rs:24:13
68+
|
69+
LL | fn test6<T: hidden_struct::library::Marker>() {}
70+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test6`
71+
72+
error: aborting due to 6 previous errors
5773

5874
Some errors have detailed explanations: E0277, E0412.
5975
For more information about an error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)