Auto merge of #89262 - Manishearth:rollup-vtkbetm, r=Manishearth
Rollup of 7 pull requests Successful merges: - #88895 (rustdoc: Cleanup `clean` part 2) - #88973 (Expose the std_detect env_override feature) - #89010 (Add some intra doc links) - #89198 (rustdoc: Don't show hidden trait methods) - #89216 (Consistent big O notation) - #89224 (Change the order of imports suggestions) - #89256 (Fix typo in release notes) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
4da89a180f
30 changed files with 207 additions and 117 deletions
|
@ -17,7 +17,7 @@ Compiler
|
|||
|
||||
- [Upgrade to LLVM 13.][rust#87570]
|
||||
- [Support memory, address, and thread sanitizers on aarch64-unknown-freebsd.][rust#88023]
|
||||
- [Allow specifying an deployment target version for all iOS targets][rust#87699]
|
||||
- [Allow specifying a deployment target version for all iOS targets][rust#87699]
|
||||
- [Warnings can be forced on with `--force-warn`.][rust#87472]
|
||||
This feature is primarily intended for usage by `cargo fix`, rather than end users.
|
||||
- [Promote `aarch64-apple-ios-sim` to Tier 2\*.][rust#87760]
|
||||
|
@ -5170,7 +5170,7 @@ Libraries
|
|||
- [Upgrade to Unicode 10.0.0][42999]
|
||||
- [Reimplemented `{f32, f64}::{min, max}` in Rust instead of using CMath.][42430]
|
||||
- [Skip the main thread's manual stack guard on Linux][43072]
|
||||
- [Iterator::nth for `ops::{Range, RangeFrom}` is now done in O(1) time][43077]
|
||||
- [Iterator::nth for `ops::{Range, RangeFrom}` is now done in *O*(1) time][43077]
|
||||
- [`#[repr(align(N))]` attribute max number is now 2^31 - 1.][43097] This was
|
||||
previously 2^15.
|
||||
- [`{OsStr, Path}::Display` now avoids allocations where possible][42613]
|
||||
|
@ -8473,7 +8473,7 @@ Libraries
|
|||
algorithm][s].
|
||||
* [`std::io::copy` allows `?Sized` arguments][cc].
|
||||
* The `Windows`, `Chunks`, and `ChunksMut` iterators over slices all
|
||||
[override `count`, `nth` and `last` with an O(1)
|
||||
[override `count`, `nth` and `last` with an *O*(1)
|
||||
implementation][it].
|
||||
* [`Default` is implemented for arrays up to `[T; 32]`][d].
|
||||
* [`IntoRawFd` has been added to the Unix-specific prelude,
|
||||
|
@ -8995,7 +8995,7 @@ Libraries
|
|||
* The `Default` implementation for `Arc` [no longer requires `Sync +
|
||||
Send`][arc].
|
||||
* [The `Iterator` methods `count`, `nth`, and `last` have been
|
||||
overridden for slices to have O(1) performance instead of O(n)][si].
|
||||
overridden for slices to have *O*(1) performance instead of *O*(*n*)][si].
|
||||
* Incorrect handling of paths on Windows has been improved in both the
|
||||
compiler and the standard library.
|
||||
* [`AtomicPtr` gained a `Default` implementation][ap].
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//! Also computes as the resulting DAG if each SCC is replaced with a
|
||||
//! node in the graph. This uses [Tarjan's algorithm](
|
||||
//! https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm)
|
||||
//! that completes in *O(n)* time.
|
||||
//! that completes in *O*(*n*) time.
|
||||
|
||||
use crate::fx::FxHashSet;
|
||||
use crate::graph::vec_graph::VecGraph;
|
||||
|
|
|
@ -9,7 +9,7 @@ mod index_map;
|
|||
pub use index_map::SortedIndexMultiMap;
|
||||
|
||||
/// `SortedMap` is a data structure with similar characteristics as BTreeMap but
|
||||
/// slightly different trade-offs: lookup, insertion, and removal are O(log(N))
|
||||
/// slightly different trade-offs: lookup, insertion, and removal are *O*(log(*n*))
|
||||
/// and elements can be iterated in order cheaply.
|
||||
///
|
||||
/// `SortedMap` can be faster than a `BTreeMap` for small sizes (<50) since it
|
||||
|
|
|
@ -1706,6 +1706,9 @@ crate fn show_candidates(
|
|||
candidates.iter().map(|c| path_names_to_string(&c.path)).collect();
|
||||
|
||||
path_strings.sort();
|
||||
let core_path_strings =
|
||||
path_strings.drain_filter(|p| p.starts_with("core::")).collect::<Vec<String>>();
|
||||
path_strings.extend(core_path_strings);
|
||||
path_strings.dedup();
|
||||
|
||||
let (determiner, kind) = if candidates.len() == 1 {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(drain_filter)]
|
||||
#![feature(bool_to_option)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(format_args_capture)]
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//! Insertion and popping the largest element have *O*(log(*n*)) time complexity.
|
||||
//! Checking the largest element is *O*(1). Converting a vector to a binary heap
|
||||
//! can be done in-place, and has *O*(*n*) complexity. A binary heap can also be
|
||||
//! converted to a sorted vector in-place, allowing it to be used for an *O*(*n* \* log(*n*))
|
||||
//! converted to a sorted vector in-place, allowing it to be used for an *O*(*n* * log(*n*))
|
||||
//! in-place heapsort.
|
||||
//!
|
||||
//! # Examples
|
||||
|
@ -159,9 +159,9 @@ use super::SpecExtend;
|
|||
/// This will be a max-heap.
|
||||
///
|
||||
/// It is a logic error for an item to be modified in such a way that the
|
||||
/// item's ordering relative to any other item, as determined by the `Ord`
|
||||
/// item's ordering relative to any other item, as determined by the [`Ord`]
|
||||
/// trait, changes while it is in the heap. This is normally only possible
|
||||
/// through `Cell`, `RefCell`, global state, I/O, or unsafe code. The
|
||||
/// through [`Cell`], [`RefCell`], global state, I/O, or unsafe code. The
|
||||
/// behavior resulting from such a logic error is not specified, but will
|
||||
/// not result in undefined behavior. This could include panics, incorrect
|
||||
/// results, aborts, memory leaks, and non-termination.
|
||||
|
@ -219,7 +219,7 @@ use super::SpecExtend;
|
|||
///
|
||||
/// ## Min-heap
|
||||
///
|
||||
/// Either `std::cmp::Reverse` or a custom `Ord` implementation can be used to
|
||||
/// Either [`core::cmp::Reverse`] or a custom [`Ord`] implementation can be used to
|
||||
/// make `BinaryHeap` a min-heap. This makes `heap.pop()` return the smallest
|
||||
/// value instead of the greatest one.
|
||||
///
|
||||
|
@ -243,13 +243,17 @@ use super::SpecExtend;
|
|||
///
|
||||
/// # Time complexity
|
||||
///
|
||||
/// | [push] | [pop] | [peek]/[peek\_mut] |
|
||||
/// |--------|-----------|--------------------|
|
||||
/// | O(1)~ | *O*(log(*n*)) | *O*(1) |
|
||||
/// | [push] | [pop] | [peek]/[peek\_mut] |
|
||||
/// |---------|---------------|--------------------|
|
||||
/// | *O*(1)~ | *O*(log(*n*)) | *O*(1) |
|
||||
///
|
||||
/// The value for `push` is an expected cost; the method documentation gives a
|
||||
/// more detailed analysis.
|
||||
///
|
||||
/// [`core::cmp::Reverse`]: core::cmp::Reverse
|
||||
/// [`Ord`]: core::cmp::Ord
|
||||
/// [`Cell`]: core::cell::Cell
|
||||
/// [`RefCell`]: core::cell::RefCell
|
||||
/// [push]: BinaryHeap::push
|
||||
/// [pop]: BinaryHeap::pop
|
||||
/// [peek]: BinaryHeap::peek
|
||||
|
@ -1255,9 +1259,10 @@ impl<T> FusedIterator for Iter<'_, T> {}
|
|||
/// An owning iterator over the elements of a `BinaryHeap`.
|
||||
///
|
||||
/// This `struct` is created by [`BinaryHeap::into_iter()`]
|
||||
/// (provided by the `IntoIterator` trait). See its documentation for more.
|
||||
/// (provided by the [`IntoIterator`] trait). See its documentation for more.
|
||||
///
|
||||
/// [`into_iter`]: BinaryHeap::into_iter
|
||||
/// [`IntoIterator`]: core::iter::IntoIterator
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[derive(Clone)]
|
||||
pub struct IntoIter<T> {
|
||||
|
|
|
@ -326,9 +326,10 @@ impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IterMut<'_, K, V> {
|
|||
/// An owning iterator over the entries of a `BTreeMap`.
|
||||
///
|
||||
/// This `struct` is created by the [`into_iter`] method on [`BTreeMap`]
|
||||
/// (provided by the `IntoIterator` trait). See its documentation for more.
|
||||
/// (provided by the [`IntoIterator`] trait). See its documentation for more.
|
||||
///
|
||||
/// [`into_iter`]: IntoIterator::into_iter
|
||||
/// [`IntoIterator`]: core::iter::IntoIterator
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct IntoIter<K, V> {
|
||||
range: LazyLeafRange<marker::Dying, K, V>,
|
||||
|
|
|
@ -107,9 +107,10 @@ impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
|
|||
/// An owning iterator over the items of a `BTreeSet`.
|
||||
///
|
||||
/// This `struct` is created by the [`into_iter`] method on [`BTreeSet`]
|
||||
/// (provided by the `IntoIterator` trait). See its documentation for more.
|
||||
/// (provided by the [`IntoIterator`] trait). See its documentation for more.
|
||||
///
|
||||
/// [`into_iter`]: BTreeSet#method.into_iter
|
||||
/// [`IntoIterator`]: core::iter::IntoIterator
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[derive(Debug)]
|
||||
pub struct IntoIter<T> {
|
||||
|
|
|
@ -38,9 +38,12 @@ mod tests;
|
|||
/// let list = LinkedList::from([1, 2, 3]);
|
||||
/// ```
|
||||
///
|
||||
/// NOTE: It is almost always better to use `Vec` or `VecDeque` because
|
||||
/// NOTE: It is almost always better to use [`Vec`] or [`VecDeque`] because
|
||||
/// array-based containers are generally faster,
|
||||
/// more memory efficient, and make better use of CPU cache.
|
||||
///
|
||||
/// [`Vec`]: crate::vec::Vec
|
||||
/// [`VecDeque`]: super::vec_deque::VecDeque
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "LinkedList")]
|
||||
pub struct LinkedList<T> {
|
||||
|
@ -121,9 +124,10 @@ impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> {
|
|||
/// An owning iterator over the elements of a `LinkedList`.
|
||||
///
|
||||
/// This `struct` is created by the [`into_iter`] method on [`LinkedList`]
|
||||
/// (provided by the `IntoIterator` trait). See its documentation for more.
|
||||
/// (provided by the [`IntoIterator`] trait). See its documentation for more.
|
||||
///
|
||||
/// [`into_iter`]: LinkedList::into_iter
|
||||
/// [`IntoIterator`]: core::iter::IntoIterator
|
||||
#[derive(Clone)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct IntoIter<T> {
|
||||
|
|
|
@ -8,9 +8,10 @@ use super::VecDeque;
|
|||
/// An owning iterator over the elements of a `VecDeque`.
|
||||
///
|
||||
/// This `struct` is created by the [`into_iter`] method on [`VecDeque`]
|
||||
/// (provided by the `IntoIterator` trait). See its documentation for more.
|
||||
/// (provided by the [`IntoIterator`] trait). See its documentation for more.
|
||||
///
|
||||
/// [`into_iter`]: VecDeque::into_iter
|
||||
/// [`IntoIterator`]: core::iter::IntoIterator
|
||||
#[derive(Clone)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct IntoIter<
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//! A contiguous growable array type with heap-allocated contents, written
|
||||
//! `Vec<T>`.
|
||||
//!
|
||||
//! Vectors have `O(1)` indexing, amortized `O(1)` push (to the end) and
|
||||
//! `O(1)` pop (from the end).
|
||||
//! Vectors have *O*(1) indexing, amortized *O*(1) push (to the end) and
|
||||
//! *O*(1) pop (from the end).
|
||||
//!
|
||||
//! Vectors ensure they never allocate more than `isize::MAX` bytes.
|
||||
//!
|
||||
|
@ -1270,7 +1270,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||
///
|
||||
/// The removed element is replaced by the last element of the vector.
|
||||
///
|
||||
/// This does not preserve ordering, but is O(1).
|
||||
/// This does not preserve ordering, but is *O*(1).
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
|
|
|
@ -1795,10 +1795,11 @@ pub trait Iterator {
|
|||
/// The relative order of partitioned items is not maintained.
|
||||
///
|
||||
/// # Current implementation
|
||||
///
|
||||
/// Current algorithms tries finding the first element for which the predicate evaluates
|
||||
/// to false, and the last element for which it evaluates to true and repeatedly swaps them.
|
||||
///
|
||||
/// Time Complexity: *O*(*N*)
|
||||
/// Time complexity: *O*(*n*)
|
||||
///
|
||||
/// See also [`is_partitioned()`] and [`partition()`].
|
||||
///
|
||||
|
|
|
@ -72,6 +72,7 @@ panic_immediate_abort = ["core/panic_immediate_abort"]
|
|||
# https://github.com/rust-lang/stdarch/blob/master/crates/std_detect/Cargo.toml
|
||||
std_detect_file_io = ["std_detect/std_detect_file_io"]
|
||||
std_detect_dlsym_getauxval = ["std_detect/std_detect_dlsym_getauxval"]
|
||||
std_detect_env_override = ["std_detect/std_detect_env_override"]
|
||||
|
||||
[package.metadata.fortanix-sgx]
|
||||
# Maximum possible number of threads when testing
|
||||
|
|
|
@ -1257,9 +1257,10 @@ impl<'a, K, V> IterMut<'a, K, V> {
|
|||
/// An owning iterator over the entries of a `HashMap`.
|
||||
///
|
||||
/// This `struct` is created by the [`into_iter`] method on [`HashMap`]
|
||||
/// (provided by the `IntoIterator` trait). See its documentation for more.
|
||||
/// (provided by the [`IntoIterator`] trait). See its documentation for more.
|
||||
///
|
||||
/// [`into_iter`]: IntoIterator::into_iter
|
||||
/// [`IntoIterator`]: crate::iter::IntoIterator
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
|
|
@ -1237,9 +1237,10 @@ pub struct Iter<'a, K: 'a> {
|
|||
/// An owning iterator over the items of a `HashSet`.
|
||||
///
|
||||
/// This `struct` is created by the [`into_iter`] method on [`HashSet`]
|
||||
/// (provided by the `IntoIterator` trait). See its documentation for more.
|
||||
/// (provided by the [`IntoIterator`] trait). See its documentation for more.
|
||||
///
|
||||
/// [`into_iter`]: IntoIterator::into_iter
|
||||
/// [`IntoIterator`]: crate::iter::IntoIterator
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -97,11 +97,11 @@
|
|||
//!
|
||||
//! ## Sequences
|
||||
//!
|
||||
//! | | get(i) | insert(i) | remove(i) | append | split_off(i) |
|
||||
//! |----------------|----------------|-----------------|----------------|--------|----------------|
|
||||
//! | [`Vec`] | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) |
|
||||
//! | [`VecDeque`] | O(1) | O(min(i, n-i))* | O(min(i, n-i)) | O(m)* | O(min(i, n-i)) |
|
||||
//! | [`LinkedList`] | O(min(i, n-i)) | O(min(i, n-i)) | O(min(i, n-i)) | O(1) | O(min(i, n-i)) |
|
||||
//! | | get(i) | insert(i) | remove(i) | append | split_off(i) |
|
||||
//! |----------------|------------------------|-------------------------|------------------------|-----------|------------------------|
|
||||
//! | [`Vec`] | *O*(1) | *O*(*n*-*i*)* | *O*(*n*-*i*) | *O*(*m*)* | *O*(*n*-*i*) |
|
||||
//! | [`VecDeque`] | *O*(1) | *O*(min(*i*, *n*-*i*))* | *O*(min(*i*, *n*-*i*)) | *O*(*m*)* | *O*(min(*i*, *n*-*i*)) |
|
||||
//! | [`LinkedList`] | *O*(min(*i*, *n*-*i*)) | *O*(min(*i*, *n*-*i*)) | *O*(min(*i*, *n*-*i*)) | *O*(1) | *O*(min(*i*, *n*-*i*)) |
|
||||
//!
|
||||
//! Note that where ties occur, [`Vec`] is generally going to be faster than [`VecDeque`], and
|
||||
//! [`VecDeque`] is generally going to be faster than [`LinkedList`].
|
||||
|
@ -110,10 +110,10 @@
|
|||
//!
|
||||
//! For Sets, all operations have the cost of the equivalent Map operation.
|
||||
//!
|
||||
//! | | get | insert | remove | range | append |
|
||||
//! |--------------|-----------|-----------|-----------|-----------|--------|
|
||||
//! | [`HashMap`] | O(1)~ | O(1)~* | O(1)~ | N/A | N/A |
|
||||
//! | [`BTreeMap`] | O(log(n)) | O(log(n)) | O(log(n)) | O(log(n)) | O(n+m) |
|
||||
//! | | get | insert | remove | range | append |
|
||||
//! |--------------|---------------|---------------|---------------|---------------|--------------|
|
||||
//! | [`HashMap`] | *O*(1)~ | *O*(1)~* | *O*(1)~ | N/A | N/A |
|
||||
//! | [`BTreeMap`] | *O*(log(*n*)) | *O*(log(*n*)) | *O*(log(*n*)) | *O*(log(*n*)) | *O*(*n*+*m*) |
|
||||
//!
|
||||
//! # Correct and Efficient Usage of Collections
|
||||
//!
|
||||
|
|
|
@ -43,8 +43,8 @@
|
|||
//! terminator, so the buffer length is really `len+1` characters.
|
||||
//! Rust strings don't have a nul terminator; their length is always
|
||||
//! stored and does not need to be calculated. While in Rust
|
||||
//! accessing a string's length is a `O(1)` operation (because the
|
||||
//! length is stored); in C it is an `O(length)` operation because the
|
||||
//! accessing a string's length is an *O*(1) operation (because the
|
||||
//! length is stored); in C it is an *O*(*n*) operation because the
|
||||
//! length needs to be computed by scanning the string for the nul
|
||||
//! terminator.
|
||||
//!
|
||||
|
|
|
@ -33,3 +33,4 @@ panic_immediate_abort = ["std/panic_immediate_abort"]
|
|||
profiler = ["std/profiler"]
|
||||
std_detect_file_io = ["std/std_detect_file_io"]
|
||||
std_detect_dlsym_getauxval = ["std/std_detect_dlsym_getauxval"]
|
||||
std_detect_env_override = ["std/std_detect_env_override"]
|
||||
|
|
|
@ -354,7 +354,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
|||
let (poly_trait, output) =
|
||||
(data.0.as_ref().unwrap().clone(), data.1.as_ref().cloned().map(Box::new));
|
||||
let new_ty = match poly_trait.trait_ {
|
||||
Type::ResolvedPath { ref path, ref did, ref is_generic } => {
|
||||
Type::ResolvedPath { ref path, ref did } => {
|
||||
let mut new_path = path.clone();
|
||||
let last_segment =
|
||||
new_path.segments.pop().expect("segments were empty");
|
||||
|
@ -389,11 +389,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
|||
.segments
|
||||
.push(PathSegment { name: last_segment.name, args: new_params });
|
||||
|
||||
Type::ResolvedPath {
|
||||
path: new_path,
|
||||
did: *did,
|
||||
is_generic: *is_generic,
|
||||
}
|
||||
Type::ResolvedPath { path: new_path, did: *did }
|
||||
}
|
||||
_ => panic!("Unexpected data: {:?}, {:?}", ty, data),
|
||||
};
|
||||
|
@ -563,11 +559,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
|||
Type::QPath { name: left_name, ref self_type, ref trait_, .. } => {
|
||||
let ty = &*self_type;
|
||||
match **trait_ {
|
||||
Type::ResolvedPath {
|
||||
path: ref trait_path,
|
||||
ref did,
|
||||
ref is_generic,
|
||||
} => {
|
||||
Type::ResolvedPath { path: ref trait_path, ref did } => {
|
||||
let mut new_trait_path = trait_path.clone();
|
||||
|
||||
if self.is_fn_ty(trait_) && left_name == sym::Output {
|
||||
|
@ -612,7 +604,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
|||
trait_: Type::ResolvedPath {
|
||||
path: new_trait_path,
|
||||
did: *did,
|
||||
is_generic: *is_generic,
|
||||
},
|
||||
generic_params: Vec::new(),
|
||||
},
|
||||
|
|
|
@ -389,13 +389,45 @@ crate fn build_impl(
|
|||
}
|
||||
}
|
||||
|
||||
let document_hidden = cx.render_options.document_hidden;
|
||||
let predicates = tcx.explicit_predicates_of(did);
|
||||
let (trait_items, generics) = match impl_item {
|
||||
Some(impl_) => (
|
||||
impl_
|
||||
.items
|
||||
.iter()
|
||||
.map(|item| tcx.hir().impl_item(item.id).clean(cx))
|
||||
.map(|item| tcx.hir().impl_item(item.id))
|
||||
.filter(|item| {
|
||||
// Filter out impl items whose corresponding trait item has `doc(hidden)`
|
||||
// not to document such impl items.
|
||||
// For inherent impls, we don't do any filtering, because that's already done in strip_hidden.rs.
|
||||
|
||||
// When `--document-hidden-items` is passed, we don't
|
||||
// do any filtering, too.
|
||||
if document_hidden {
|
||||
return true;
|
||||
}
|
||||
if let Some(associated_trait) = associated_trait {
|
||||
let assoc_kind = match item.kind {
|
||||
hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
|
||||
hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn,
|
||||
hir::ImplItemKind::TyAlias(..) => ty::AssocKind::Type,
|
||||
};
|
||||
let trait_item = tcx
|
||||
.associated_items(associated_trait.def_id)
|
||||
.find_by_name_and_kind(
|
||||
tcx,
|
||||
item.ident,
|
||||
assoc_kind,
|
||||
associated_trait.def_id,
|
||||
)
|
||||
.unwrap(); // SAFETY: For all impl items there exists trait item that has the same name.
|
||||
!tcx.get_attrs(trait_item.def_id).lists(sym::doc).has_word(sym::hidden)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
})
|
||||
.map(|item| item.clean(cx))
|
||||
.collect::<Vec<_>>(),
|
||||
impl_.generics.clean(cx),
|
||||
),
|
||||
|
|
|
@ -168,7 +168,7 @@ impl Clean<Type> for (ty::TraitRef<'_>, &[TypeBinding]) {
|
|||
|
||||
debug!("ty::TraitRef\n subst: {:?}\n", trait_ref.substs);
|
||||
|
||||
ResolvedPath { path, did: trait_ref.def_id, is_generic: false }
|
||||
ResolvedPath { path, did: trait_ref.def_id }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1440,12 +1440,12 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
|||
};
|
||||
inline::record_extern_fqn(cx, did, kind);
|
||||
let path = external_path(cx, did, false, vec![], substs);
|
||||
ResolvedPath { path, did, is_generic: false }
|
||||
ResolvedPath { path, did }
|
||||
}
|
||||
ty::Foreign(did) => {
|
||||
inline::record_extern_fqn(cx, did, ItemType::ForeignType);
|
||||
let path = external_path(cx, did, false, vec![], InternalSubsts::empty());
|
||||
ResolvedPath { path, did, is_generic: false }
|
||||
ResolvedPath { path, did }
|
||||
}
|
||||
ty::Dynamic(ref obj, ref reg) => {
|
||||
// HACK: pick the first `did` as the `did` of the trait object. Someone
|
||||
|
@ -1471,7 +1471,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
|||
let path = external_path(cx, did, false, vec![], empty);
|
||||
inline::record_extern_fqn(cx, did, ItemType::Trait);
|
||||
let bound = PolyTrait {
|
||||
trait_: ResolvedPath { path, did, is_generic: false },
|
||||
trait_: ResolvedPath { path, did },
|
||||
generic_params: Vec::new(),
|
||||
};
|
||||
bounds.push(bound);
|
||||
|
@ -1488,10 +1488,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
|||
let path = external_path(cx, did, false, bindings, substs);
|
||||
bounds.insert(
|
||||
0,
|
||||
PolyTrait {
|
||||
trait_: ResolvedPath { path, did, is_generic: false },
|
||||
generic_params: Vec::new(),
|
||||
},
|
||||
PolyTrait { trait_: ResolvedPath { path, did }, generic_params: Vec::new() },
|
||||
);
|
||||
|
||||
DynTrait(bounds, lifetime)
|
||||
|
|
|
@ -1114,10 +1114,7 @@ impl GenericBound {
|
|||
let path = external_path(cx, did, false, vec![], empty);
|
||||
inline::record_extern_fqn(cx, did, ItemType::Trait);
|
||||
GenericBound::TraitBound(
|
||||
PolyTrait {
|
||||
trait_: ResolvedPath { path, did, is_generic: false },
|
||||
generic_params: Vec::new(),
|
||||
},
|
||||
PolyTrait { trait_: ResolvedPath { path, did }, generic_params: Vec::new() },
|
||||
hir::TraitBoundModifier::Maybe,
|
||||
)
|
||||
}
|
||||
|
@ -1384,8 +1381,6 @@ crate enum Type {
|
|||
ResolvedPath {
|
||||
path: Path,
|
||||
did: DefId,
|
||||
/// `true` if is a `T::Name` path for associated types.
|
||||
is_generic: bool,
|
||||
},
|
||||
/// `dyn for<'a> Trait<'a> + Send + 'static`
|
||||
DynTrait(Vec<PolyTrait>, Option<Lifetime>),
|
||||
|
@ -1503,9 +1498,10 @@ impl Type {
|
|||
}
|
||||
}
|
||||
|
||||
crate fn is_generic(&self) -> bool {
|
||||
match *self {
|
||||
ResolvedPath { is_generic, .. } => is_generic,
|
||||
/// Checks if this is a `T::Name` path for an associated type.
|
||||
crate fn is_assoc_ty(&self) -> bool {
|
||||
match self {
|
||||
ResolvedPath { path, .. } => path.is_assoc_ty(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -1994,6 +1990,16 @@ impl Path {
|
|||
String::from(if self.global { "::" } else { "" })
|
||||
+ &self.segments.iter().map(|s| s.name.to_string()).collect::<Vec<_>>().join("::")
|
||||
}
|
||||
|
||||
/// Checks if this is a `T::Name` path for an associated type.
|
||||
crate fn is_assoc_ty(&self) -> bool {
|
||||
match self.res {
|
||||
Res::SelfTy(..) if self.segments.len() != 1 => true,
|
||||
Res::Def(DefKind::TyParam, _) if self.segments.len() != 1 => true,
|
||||
Res::Def(DefKind::AssocTy, _) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
|
|
|
@ -159,9 +159,7 @@ pub(super) fn external_path(
|
|||
|
||||
crate fn strip_type(ty: Type) -> Type {
|
||||
match ty {
|
||||
Type::ResolvedPath { path, did, is_generic } => {
|
||||
Type::ResolvedPath { path: strip_path(&path), did, is_generic }
|
||||
}
|
||||
Type::ResolvedPath { path, did } => Type::ResolvedPath { path: strip_path(&path), did },
|
||||
Type::DynTrait(mut bounds, lt) => {
|
||||
let first = bounds.remove(0);
|
||||
let stripped_trait = strip_type(first.trait_);
|
||||
|
@ -404,19 +402,15 @@ crate fn print_const_expr(tcx: TyCtxt<'_>, body: hir::BodyId) -> String {
|
|||
crate fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type {
|
||||
debug!("resolve_type({:?})", path);
|
||||
|
||||
let is_generic = match path.res {
|
||||
Res::PrimTy(p) => return Primitive(PrimitiveType::from(p)),
|
||||
Res::SelfTy(..) if path.segments.len() == 1 => {
|
||||
return Generic(kw::SelfUpper);
|
||||
match path.res {
|
||||
Res::PrimTy(p) => Primitive(PrimitiveType::from(p)),
|
||||
Res::SelfTy(..) if path.segments.len() == 1 => Generic(kw::SelfUpper),
|
||||
Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => Generic(path.segments[0].name),
|
||||
_ => {
|
||||
let did = register_res(cx, path.res);
|
||||
ResolvedPath { path, did }
|
||||
}
|
||||
Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => {
|
||||
return Generic(path.segments[0].name);
|
||||
}
|
||||
Res::SelfTy(..) | Res::Def(DefKind::TyParam | DefKind::AssocTy, _) => true,
|
||||
_ => false,
|
||||
};
|
||||
let did = register_res(cx, path.res);
|
||||
ResolvedPath { path, did, is_generic }
|
||||
}
|
||||
}
|
||||
|
||||
crate fn get_auto_trait_and_blanket_impls(
|
||||
|
|
|
@ -752,9 +752,9 @@ fn fmt_type<'cx>(
|
|||
|
||||
match *t {
|
||||
clean::Generic(name) => write!(f, "{}", name),
|
||||
clean::ResolvedPath { did, ref path, is_generic } => {
|
||||
clean::ResolvedPath { did, ref path } => {
|
||||
// Paths like `T::Output` and `Self::Output` should be rendered with all segments.
|
||||
resolved_path(f, did, path, is_generic, use_absolute, cx)
|
||||
resolved_path(f, did, path, path.is_assoc_ty(), use_absolute, cx)
|
||||
}
|
||||
clean::DynTrait(ref bounds, ref lt) => {
|
||||
f.write_str("dyn ")?;
|
||||
|
@ -825,28 +825,17 @@ fn fmt_type<'cx>(
|
|||
hir::Mutability::Mut => "mut",
|
||||
hir::Mutability::Not => "const",
|
||||
};
|
||||
match **t {
|
||||
clean::Generic(_) | clean::ResolvedPath { is_generic: true, .. } => {
|
||||
if f.alternate() {
|
||||
primitive_link(
|
||||
f,
|
||||
clean::PrimitiveType::RawPointer,
|
||||
&format!("*{} {:#}", m, t.print(cx)),
|
||||
cx,
|
||||
)
|
||||
} else {
|
||||
primitive_link(
|
||||
f,
|
||||
clean::PrimitiveType::RawPointer,
|
||||
&format!("*{} {}", m, t.print(cx)),
|
||||
cx,
|
||||
)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
primitive_link(f, clean::PrimitiveType::RawPointer, &format!("*{} ", m), cx)?;
|
||||
fmt::Display::fmt(&t.print(cx), f)
|
||||
}
|
||||
|
||||
if matches!(**t, clean::Generic(_)) || t.is_assoc_ty() {
|
||||
let text = if f.alternate() {
|
||||
format!("*{} {:#}", m, t.print(cx))
|
||||
} else {
|
||||
format!("*{} {}", m, t.print(cx))
|
||||
};
|
||||
primitive_link(f, clean::PrimitiveType::RawPointer, &text, cx)
|
||||
} else {
|
||||
primitive_link(f, clean::PrimitiveType::RawPointer, &format!("*{} ", m), cx)?;
|
||||
fmt::Display::fmt(&t.print(cx), f)
|
||||
}
|
||||
}
|
||||
clean::BorrowedRef { lifetime: ref l, mutability, type_: ref ty } => {
|
||||
|
|
|
@ -712,11 +712,10 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
|
|||
let mut implementor_dups: FxHashMap<Symbol, (DefId, bool)> = FxHashMap::default();
|
||||
for implementor in implementors {
|
||||
match implementor.inner_impl().for_ {
|
||||
clean::ResolvedPath { ref path, did, is_generic: false, .. }
|
||||
clean::ResolvedPath { ref path, did, .. }
|
||||
| clean::BorrowedRef {
|
||||
type_: box clean::ResolvedPath { ref path, did, is_generic: false, .. },
|
||||
..
|
||||
} => {
|
||||
type_: box clean::ResolvedPath { ref path, did, .. }, ..
|
||||
} if !path.is_assoc_ty() => {
|
||||
let &mut (prev_did, ref mut has_duplicates) =
|
||||
implementor_dups.entry(path.last()).or_insert((did, false));
|
||||
if prev_did != did {
|
||||
|
@ -1410,11 +1409,12 @@ fn render_implementor(
|
|||
// If there's already another implementor that has the same abridged name, use the
|
||||
// full path, for example in `std::iter::ExactSizeIterator`
|
||||
let use_absolute = match implementor.inner_impl().for_ {
|
||||
clean::ResolvedPath { ref path, is_generic: false, .. }
|
||||
| clean::BorrowedRef {
|
||||
type_: box clean::ResolvedPath { ref path, is_generic: false, .. },
|
||||
..
|
||||
} => implementor_dups[&path.last()].1,
|
||||
clean::ResolvedPath { ref path, .. }
|
||||
| clean::BorrowedRef { type_: box clean::ResolvedPath { ref path, .. }, .. }
|
||||
if !path.is_assoc_ty() =>
|
||||
{
|
||||
implementor_dups[&path.last()].1
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
render_impl(
|
||||
|
|
|
@ -387,7 +387,7 @@ impl FromWithTcx<clean::Type> for Type {
|
|||
fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self {
|
||||
use clean::Type::*;
|
||||
match ty {
|
||||
ResolvedPath { path, did, is_generic: _ } => Type::ResolvedPath {
|
||||
ResolvedPath { path, did } => Type::ResolvedPath {
|
||||
name: path.whole_name(),
|
||||
id: from_item_id(did.into()),
|
||||
args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
|
||||
|
|
|
@ -128,7 +128,7 @@ impl<'a> DocFolder for ImplStripper<'a> {
|
|||
return None;
|
||||
}
|
||||
if let Some(did) = imp.for_.def_id() {
|
||||
if did.is_local() && !imp.for_.is_generic() && !self.retained.contains(&did.into())
|
||||
if did.is_local() && !imp.for_.is_assoc_ty() && !self.retained.contains(&did.into())
|
||||
{
|
||||
debug!("ImplStripper: impl item for stripped type; removing");
|
||||
return None;
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
// compile-flags: -Z unstable-options --document-hidden-items
|
||||
|
||||
// test for trait methods with `doc(hidden)` with `--document-hidden-items` passed.
|
||||
#![crate_name = "foo"]
|
||||
|
||||
// @has foo/trait.Trait.html
|
||||
// @has - '//*[@id="associatedtype.Foo"]' 'type Foo'
|
||||
// @has - '//*[@id="associatedtype.Bar"]' 'type Bar'
|
||||
// @has - '//*[@id="tymethod.f"]' 'fn f()'
|
||||
// @has - '//*[@id="tymethod.g"]' 'fn g()'
|
||||
pub trait Trait {
|
||||
#[doc(hidden)]
|
||||
type Foo;
|
||||
type Bar;
|
||||
#[doc(hidden)]
|
||||
fn f();
|
||||
fn g();
|
||||
}
|
||||
|
||||
// @has foo/struct.S.html
|
||||
// @has - '//*[@id="associatedtype.Foo"]' 'type Foo'
|
||||
// @has - '//*[@id="associatedtype.Bar"]' 'type Bar'
|
||||
// @has - '//*[@id="method.f"]' 'fn f()'
|
||||
// @has - '//*[@id="method.g"]' 'fn g()'
|
||||
pub struct S;
|
||||
impl Trait for S {
|
||||
type Foo = ();
|
||||
type Bar = ();
|
||||
fn f() {}
|
||||
fn g() {}
|
||||
}
|
29
src/test/rustdoc/hidden-trait-methods.rs
Normal file
29
src/test/rustdoc/hidden-trait-methods.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
// test for trait methods with `doc(hidden)`.
|
||||
#![crate_name = "foo"]
|
||||
|
||||
// @has foo/trait.Trait.html
|
||||
// @!has - '//*[@id="associatedtype.Foo"]' 'type Foo'
|
||||
// @has - '//*[@id="associatedtype.Bar"]' 'type Bar'
|
||||
// @!has - '//*[@id="tymethod.f"]' 'fn f()'
|
||||
// @has - '//*[@id="tymethod.g"]' 'fn g()'
|
||||
pub trait Trait {
|
||||
#[doc(hidden)]
|
||||
type Foo;
|
||||
type Bar;
|
||||
#[doc(hidden)]
|
||||
fn f();
|
||||
fn g();
|
||||
}
|
||||
|
||||
// @has foo/struct.S.html
|
||||
// @!has - '//*[@id="associatedtype.Foo"]' 'type Foo'
|
||||
// @has - '//*[@id="associatedtype.Bar"]' 'type Bar'
|
||||
// @!has - '//*[@id="method.f"]' 'fn f()'
|
||||
// @has - '//*[@id="method.g"]' 'fn g()'
|
||||
pub struct S;
|
||||
impl Trait for S {
|
||||
type Foo = ();
|
||||
type Bar = ();
|
||||
fn f() {}
|
||||
fn g() {}
|
||||
}
|
|
@ -995,7 +995,7 @@ declare_clippy_lint! {
|
|||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for use of `.iter().nth()` (and the related
|
||||
/// `.iter_mut().nth()`) on standard library types with O(1) element access.
|
||||
/// `.iter_mut().nth()`) on standard library types with *O*(1) element access.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// `.get()` and `.get_mut()` are more efficient and more
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue