Rollup merge of #149185 - Jules-Bertholet:fix-149092, r=chenyukang

Handle cycles when checking impl candidates for `doc(hidden)`

Fixes https://github.com/rust-lang/rust/issues/149092
This commit is contained in:
Matthias Krüger 2025-11-22 18:41:23 +01:00 committed by GitHub
commit cb50c01887
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 43 additions and 5 deletions

View file

@ -1,12 +1,13 @@
// ignore-tidy-filelength
use core::ops::ControlFlow;
use std::borrow::Cow;
use std::collections::hash_set;
use std::path::PathBuf;
use rustc_abi::ExternAbi;
use rustc_ast::ast::LitKind;
use rustc_ast::{LitIntType, TraitObjectSyntax};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::unord::UnordSet;
use rustc_errors::codes::*;
use rustc_errors::{
@ -1952,11 +1953,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
if self.tcx.visibility(did).is_accessible_from(body_def_id, self.tcx) {
// don't suggest foreign `#[doc(hidden)]` types
if !did.is_local() {
while let Some(parent) = parent_map.get(&did) {
let mut previously_seen_dids: FxHashSet<DefId> = Default::default();
previously_seen_dids.insert(did);
while let Some(&parent) = parent_map.get(&did)
&& let hash_set::Entry::Vacant(v) =
previously_seen_dids.entry(parent)
{
if self.tcx.is_doc_hidden(did) {
return false;
}
did = *parent;
v.insert();
did = parent;
}
}
true

View file

@ -17,6 +17,7 @@
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
#![feature(default_field_values)]
#![feature(hash_set_entry)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(iterator_try_reduce)]

View file

@ -33,3 +33,6 @@ impl Marker for hidden::Foo {}
impl Marker for hidden1::Bar {}
impl Marker for Baz {}
impl Marker for Quux {}
pub use crate as library;

View file

@ -21,7 +21,12 @@ pub fn test4(_: Quux) {}
fn test5<T: hidden_struct::Marker>() {}
fn test6<T: hidden_struct::library::Marker>() {}
fn main() {
test5::<i32>();
//~^ ERROR [E0277]
test6::<i32>();
//~^ ERROR [E0277]
}

View file

@ -38,7 +38,7 @@ LL + use hidden_struct::Quux;
|
error[E0277]: the trait bound `i32: Marker` is not satisfied
--> $DIR/dont-suggest-foreign-doc-hidden.rs:25:13
--> $DIR/dont-suggest-foreign-doc-hidden.rs:27:13
|
LL | test5::<i32>();
| ^^^ the trait `Marker` is not implemented for `i32`
@ -59,7 +59,29 @@ note: required by a bound in `test5`
LL | fn test5<T: hidden_struct::Marker>() {}
| ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test5`
error: aborting due to 5 previous errors
error[E0277]: the trait bound `i32: Marker` is not satisfied
--> $DIR/dont-suggest-foreign-doc-hidden.rs:30:13
|
LL | test6::<i32>();
| ^^^ the trait `Marker` is not implemented for `i32`
|
help: the following other types implement trait `Marker`
--> $DIR/auxiliary/hidden-struct.rs:31:1
|
LL | impl Marker for Option<u32> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Option<u32>`
...
LL | impl Marker for Baz {}
| ^^^^^^^^^^^^^^^^^^^ `Baz`
LL | impl Marker for Quux {}
| ^^^^^^^^^^^^^^^^^^^^ `Quux`
note: required by a bound in `test6`
--> $DIR/dont-suggest-foreign-doc-hidden.rs:24:13
|
LL | fn test6<T: hidden_struct::library::Marker>() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test6`
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0277, E0412.
For more information about an error, try `rustc --explain E0277`.