Handle cycles when checking impl candidates for doc(hidden)
Fixes https://github.com/rust-lang/rust/issues/149092
(cherry picked from commit f580357863)
This commit is contained in:
parent
73018d7670
commit
b1a2cb2fe0
5 changed files with 37 additions and 5 deletions
|
|
@ -1,11 +1,12 @@
|
|||
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::{
|
||||
|
|
@ -1927,11 +1928,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
|
||||
|
|
|
|||
|
|
@ -20,6 +20,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)]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
@ -53,7 +53,23 @@ 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`:
|
||||
Baz
|
||||
Option<u32>
|
||||
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`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue