Auto merge of #73779 - Manishearth:rollup-lwqd9jm, r=Manishearth
Rollup of 12 pull requests Successful merges: - #72771 (Warn if linking to a private item) - #72937 (Fortanix SGX target libunwind build process changes) - #73485 (Perform obligation deduplication to avoid buggy `ExistentialMismatch`) - #73529 (Add liballoc impl SpecFromElem for i8) - #73579 (add missing doc links) - #73627 (Shortcuts for min/max on double-ended BTreeMap/BTreeSet iterators) - #73691 (Bootstrap: detect Windows based on sys.platform) - #73694 (Document the Self keyword) - #73718 (Document the super keyword) - #73728 (Document some invariants correctly/more) - #73738 (Remove irrelevant comment) - #73765 (Remove blank line) Failed merges: r? @ghost
This commit is contained in:
commit
394e1b40d2
29 changed files with 445 additions and 116 deletions
|
|
@ -184,6 +184,7 @@ def default_build_triple():
|
|||
ostype = require(["uname", "-s"], exit=required)
|
||||
cputype = require(['uname', '-m'], exit=required)
|
||||
|
||||
# If we do not have `uname`, assume Windows.
|
||||
if ostype is None or cputype is None:
|
||||
return 'x86_64-pc-windows-msvc'
|
||||
|
||||
|
|
@ -236,6 +237,11 @@ def default_build_triple():
|
|||
if ostype.endswith('WOW64'):
|
||||
cputype = 'x86_64'
|
||||
ostype = 'pc-windows-gnu'
|
||||
elif sys.platform == 'win32':
|
||||
# Some Windows platforms might have a `uname` command that returns a
|
||||
# non-standard string (e.g. gnuwin32 tools returns `windows32`). In
|
||||
# these cases, fall back to using sys.platform.
|
||||
return 'x86_64-pc-windows-msvc'
|
||||
else:
|
||||
err = "unknown OS type: {}".format(ostype)
|
||||
sys.exit(err)
|
||||
|
|
|
|||
|
|
@ -131,26 +131,13 @@ fn copy_third_party_objects(
|
|||
compiler: &Compiler,
|
||||
target: Interned<String>,
|
||||
) -> Vec<(PathBuf, DependencyType)> {
|
||||
let libdir = builder.sysroot_libdir(*compiler, target);
|
||||
let mut target_deps = vec![];
|
||||
|
||||
// Copies libunwind.a compiled to be linked with x86_64-fortanix-unknown-sgx.
|
||||
//
|
||||
// This target needs to be linked to Fortanix's port of llvm's libunwind.
|
||||
// libunwind requires support for rwlock and printing to stderr,
|
||||
// which is provided by std for this target.
|
||||
// FIXME: remove this in 2021
|
||||
if target == "x86_64-fortanix-unknown-sgx" {
|
||||
let src_path_env = "X86_FORTANIX_SGX_LIBS";
|
||||
let src =
|
||||
env::var(src_path_env).unwrap_or_else(|_| panic!("{} not found in env", src_path_env));
|
||||
copy_and_stamp(
|
||||
builder,
|
||||
&*libdir,
|
||||
Path::new(&src),
|
||||
"libunwind.a",
|
||||
&mut target_deps,
|
||||
DependencyType::Target,
|
||||
);
|
||||
if env::var_os("X86_FORTANIX_SGX_LIBS").is_some() {
|
||||
builder.info("Warning: X86_FORTANIX_SGX_LIBS environment variable is ignored, libunwind is now compiled as part of rustbuild");
|
||||
}
|
||||
}
|
||||
|
||||
if builder.config.sanitizers && compiler.stage != 0 {
|
||||
|
|
|
|||
|
|
@ -71,9 +71,7 @@ RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc
|
|||
COPY dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh /tmp/
|
||||
COPY dist-various-2/x86_64-fortanix-unknown-sgx-clang-wrap.sh /usr/bin/x86_64-fortanix-unknown-sgx-clang-11
|
||||
RUN ln -s /usr/bin/x86_64-fortanix-unknown-sgx-clang-11 /usr/bin/x86_64-fortanix-unknown-sgx-clang++-11
|
||||
# We pass the commit id of the port of LLVM's libunwind to the build script.
|
||||
# Any update to the commit id here, should cause the container image to be re-built from this point on.
|
||||
RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh "800f95131fe6acd20b96b6f4723ca3c820f3d379"
|
||||
RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh
|
||||
|
||||
COPY dist-various-2/build-wasi-toolchain.sh /tmp/
|
||||
RUN /tmp/build-wasi-toolchain.sh
|
||||
|
|
@ -105,8 +103,6 @@ ENV TARGETS=$TARGETS,nvptx64-nvidia-cuda
|
|||
ENV TARGETS=$TARGETS,armv7-unknown-linux-gnueabi
|
||||
ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabi
|
||||
|
||||
ENV X86_FORTANIX_SGX_LIBS="/x86_64-fortanix-unknown-sgx/lib/"
|
||||
|
||||
# As per https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1300211
|
||||
# we need asm in the search path for gcc-7 (for gnux32) but not in the search path of the
|
||||
# cross compilers.
|
||||
|
|
|
|||
|
|
@ -3,14 +3,7 @@
|
|||
set -eu
|
||||
source shared.sh
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: ${0} <commit_id>"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
target="x86_64-fortanix-unknown-sgx"
|
||||
url="https://github.com/fortanix/llvm-project/archive/${1}.tar.gz"
|
||||
repo_name="llvm-project"
|
||||
|
||||
install_prereq() {
|
||||
curl https://apt.llvm.org/llvm-snapshot.gpg.key|apt-key add -
|
||||
|
|
@ -24,39 +17,4 @@ install_prereq() {
|
|||
clang-11
|
||||
}
|
||||
|
||||
build_unwind() {
|
||||
set -x
|
||||
dir_name="${target}_temp"
|
||||
rm -rf ${dir_name}
|
||||
mkdir -p ${dir_name}
|
||||
pushd ${dir_name}
|
||||
|
||||
# Clone Fortanix's fork of llvm-project which has a port of libunwind
|
||||
fetch_github_commit_archive "$repo_name" "$url"
|
||||
cd "${repo_name}/libunwind"
|
||||
|
||||
# Build libunwind
|
||||
mkdir -p build
|
||||
cd build
|
||||
target_CC="CC_${target//-/_}"
|
||||
target_CXX="CXX_${target//-/_}"
|
||||
target_CFLAGS="CFLAGS_${target//-/_}"
|
||||
target_CXXFLAGS="CXXFLAGS_${target//-/_}"
|
||||
cmake -DCMAKE_BUILD_TYPE="RELEASE" -DRUST_SGX=1 -G "Unix Makefiles" \
|
||||
-DCMAKE_C_COMPILER="${!target_CC}" -DCMAKE_CXX_COMPILER="${!target_CXX}" \
|
||||
-DCMAKE_C_FLAGS="${!target_CFLAGS}" -DCMAKE_CXX_FLAGS="${!target_CXXFLAGS}" \
|
||||
-DCMAKE_C_COMPILER_TARGET=$target -DCMAKE_CXX_COMPILER_TARGET=$target \
|
||||
-DLLVM_ENABLE_WARNINGS=1 -DLIBUNWIND_ENABLE_WERROR=1 -DLIBUNWIND_ENABLE_PEDANTIC=0 \
|
||||
-DLLVM_PATH=../../llvm/ ../
|
||||
make unwind_static
|
||||
install -D "lib/libunwind.a" "/${target}/lib/libunwind.a"
|
||||
|
||||
popd
|
||||
rm -rf ${dir_name}
|
||||
|
||||
{ set +x; } 2>/dev/null
|
||||
}
|
||||
|
||||
set -x
|
||||
hide_output install_prereq
|
||||
build_unwind
|
||||
|
|
|
|||
|
|
@ -1396,6 +1396,14 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> {
|
|||
fn last(mut self) -> Option<(&'a K, &'a V)> {
|
||||
self.next_back()
|
||||
}
|
||||
|
||||
fn min(mut self) -> Option<(&'a K, &'a V)> {
|
||||
self.next()
|
||||
}
|
||||
|
||||
fn max(mut self) -> Option<(&'a K, &'a V)> {
|
||||
self.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
|
|
@ -1458,6 +1466,14 @@ impl<'a, K: 'a, V: 'a> Iterator for IterMut<'a, K, V> {
|
|||
fn last(mut self) -> Option<(&'a K, &'a mut V)> {
|
||||
self.next_back()
|
||||
}
|
||||
|
||||
fn min(mut self) -> Option<(&'a K, &'a mut V)> {
|
||||
self.next()
|
||||
}
|
||||
|
||||
fn max(mut self) -> Option<(&'a K, &'a mut V)> {
|
||||
self.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
|
@ -1595,6 +1611,14 @@ impl<'a, K, V> Iterator for Keys<'a, K, V> {
|
|||
fn last(mut self) -> Option<&'a K> {
|
||||
self.next_back()
|
||||
}
|
||||
|
||||
fn min(mut self) -> Option<&'a K> {
|
||||
self.next()
|
||||
}
|
||||
|
||||
fn max(mut self) -> Option<&'a K> {
|
||||
self.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
|
@ -1768,6 +1792,14 @@ impl<'a, K, V> Iterator for Range<'a, K, V> {
|
|||
fn last(mut self) -> Option<(&'a K, &'a V)> {
|
||||
self.next_back()
|
||||
}
|
||||
|
||||
fn min(mut self) -> Option<(&'a K, &'a V)> {
|
||||
self.next()
|
||||
}
|
||||
|
||||
fn max(mut self) -> Option<(&'a K, &'a V)> {
|
||||
self.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "map_values_mut", since = "1.10.0")]
|
||||
|
|
@ -1853,6 +1885,14 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> {
|
|||
fn last(mut self) -> Option<(&'a K, &'a mut V)> {
|
||||
self.next_back()
|
||||
}
|
||||
|
||||
fn min(mut self) -> Option<(&'a K, &'a mut V)> {
|
||||
self.next()
|
||||
}
|
||||
|
||||
fn max(mut self) -> Option<(&'a K, &'a mut V)> {
|
||||
self.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K, V> RangeMut<'a, K, V> {
|
||||
|
|
|
|||
|
|
@ -1291,12 +1291,22 @@ impl<'a, T> Iterator for Iter<'a, T> {
|
|||
fn next(&mut self) -> Option<&'a T> {
|
||||
self.iter.next()
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.iter.size_hint()
|
||||
}
|
||||
|
||||
fn last(mut self) -> Option<&'a T> {
|
||||
self.next_back()
|
||||
}
|
||||
|
||||
fn min(mut self) -> Option<&'a T> {
|
||||
self.next()
|
||||
}
|
||||
|
||||
fn max(mut self) -> Option<&'a T> {
|
||||
self.next_back()
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
|
||||
|
|
@ -1321,6 +1331,7 @@ impl<T> Iterator for IntoIter<T> {
|
|||
fn next(&mut self) -> Option<T> {
|
||||
self.iter.next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.iter.size_hint()
|
||||
}
|
||||
|
|
@ -1359,6 +1370,14 @@ impl<'a, T> Iterator for Range<'a, T> {
|
|||
fn last(mut self) -> Option<&'a T> {
|
||||
self.next_back()
|
||||
}
|
||||
|
||||
fn min(mut self) -> Option<&'a T> {
|
||||
self.next()
|
||||
}
|
||||
|
||||
fn max(mut self) -> Option<&'a T> {
|
||||
self.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "btree_range", since = "1.17.0")]
|
||||
|
|
@ -1429,6 +1448,10 @@ impl<'a, T: Ord> Iterator for Difference<'a, T> {
|
|||
};
|
||||
(self_len.saturating_sub(other_len), Some(self_len))
|
||||
}
|
||||
|
||||
fn min(mut self) -> Option<&'a T> {
|
||||
self.next()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
|
|
@ -1460,6 +1483,10 @@ impl<'a, T: Ord> Iterator for SymmetricDifference<'a, T> {
|
|||
// the number of elements to less than half the range of usize.
|
||||
(0, Some(a_len + b_len))
|
||||
}
|
||||
|
||||
fn min(mut self) -> Option<&'a T> {
|
||||
self.next()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
|
|
@ -1516,6 +1543,10 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> {
|
|||
IntersectionInner::Answer(Some(_)) => (1, Some(1)),
|
||||
}
|
||||
}
|
||||
|
||||
fn min(mut self) -> Option<&'a T> {
|
||||
self.next()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
|
|
@ -1541,6 +1572,10 @@ impl<'a, T: Ord> Iterator for Union<'a, T> {
|
|||
// No checked_add - see SymmetricDifference::size_hint.
|
||||
(max(a_len, b_len), Some(a_len + b_len))
|
||||
}
|
||||
|
||||
fn min(mut self) -> Option<&'a T> {
|
||||
self.next()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ fn allocator_param() {
|
|||
//
|
||||
// Instead, this just checks that the `RawVec` methods do at
|
||||
// least go through the Allocator API when it reserves
|
||||
|
||||
// storage.
|
||||
|
||||
// A dumb allocator that consumes a fixed amount of fuel
|
||||
|
|
|
|||
|
|
@ -309,6 +309,41 @@ fn test_iter_mixed() {
|
|||
test(size, map.into_iter());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iter_min_max() {
|
||||
let mut a = BTreeMap::new();
|
||||
assert_eq!(a.iter().min(), None);
|
||||
assert_eq!(a.iter().max(), None);
|
||||
assert_eq!(a.iter_mut().min(), None);
|
||||
assert_eq!(a.iter_mut().max(), None);
|
||||
assert_eq!(a.range(..).min(), None);
|
||||
assert_eq!(a.range(..).max(), None);
|
||||
assert_eq!(a.range_mut(..).min(), None);
|
||||
assert_eq!(a.range_mut(..).max(), None);
|
||||
assert_eq!(a.keys().min(), None);
|
||||
assert_eq!(a.keys().max(), None);
|
||||
assert_eq!(a.values().min(), None);
|
||||
assert_eq!(a.values().max(), None);
|
||||
assert_eq!(a.values_mut().min(), None);
|
||||
assert_eq!(a.values_mut().max(), None);
|
||||
a.insert(1, 42);
|
||||
a.insert(2, 24);
|
||||
assert_eq!(a.iter().min(), Some((&1, &42)));
|
||||
assert_eq!(a.iter().max(), Some((&2, &24)));
|
||||
assert_eq!(a.iter_mut().min(), Some((&1, &mut 42)));
|
||||
assert_eq!(a.iter_mut().max(), Some((&2, &mut 24)));
|
||||
assert_eq!(a.range(..).min(), Some((&1, &42)));
|
||||
assert_eq!(a.range(..).max(), Some((&2, &24)));
|
||||
assert_eq!(a.range_mut(..).min(), Some((&1, &mut 42)));
|
||||
assert_eq!(a.range_mut(..).max(), Some((&2, &mut 24)));
|
||||
assert_eq!(a.keys().min(), Some(&1));
|
||||
assert_eq!(a.keys().max(), Some(&2));
|
||||
assert_eq!(a.values().min(), Some(&24));
|
||||
assert_eq!(a.values().max(), Some(&42));
|
||||
assert_eq!(a.values_mut().min(), Some(&mut 24));
|
||||
assert_eq!(a.values_mut().max(), Some(&mut 42));
|
||||
}
|
||||
|
||||
fn range_keys(map: &BTreeMap<i32, i32>, range: impl RangeBounds<i32>) -> Vec<i32> {
|
||||
map.range(range)
|
||||
.map(|(&k, &v)| {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,37 @@ fn test_hash() {
|
|||
assert_eq!(hash(&x), hash(&y));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iter_min_max() {
|
||||
let mut a = BTreeSet::new();
|
||||
assert_eq!(a.iter().min(), None);
|
||||
assert_eq!(a.iter().max(), None);
|
||||
assert_eq!(a.range(..).min(), None);
|
||||
assert_eq!(a.range(..).max(), None);
|
||||
assert_eq!(a.difference(&BTreeSet::new()).min(), None);
|
||||
assert_eq!(a.difference(&BTreeSet::new()).max(), None);
|
||||
assert_eq!(a.intersection(&a).min(), None);
|
||||
assert_eq!(a.intersection(&a).max(), None);
|
||||
assert_eq!(a.symmetric_difference(&BTreeSet::new()).min(), None);
|
||||
assert_eq!(a.symmetric_difference(&BTreeSet::new()).max(), None);
|
||||
assert_eq!(a.union(&a).min(), None);
|
||||
assert_eq!(a.union(&a).max(), None);
|
||||
a.insert(1);
|
||||
a.insert(2);
|
||||
assert_eq!(a.iter().min(), Some(&1));
|
||||
assert_eq!(a.iter().max(), Some(&2));
|
||||
assert_eq!(a.range(..).min(), Some(&1));
|
||||
assert_eq!(a.range(..).max(), Some(&2));
|
||||
assert_eq!(a.difference(&BTreeSet::new()).min(), Some(&1));
|
||||
assert_eq!(a.difference(&BTreeSet::new()).max(), Some(&2));
|
||||
assert_eq!(a.intersection(&a).min(), Some(&1));
|
||||
assert_eq!(a.intersection(&a).max(), Some(&2));
|
||||
assert_eq!(a.symmetric_difference(&BTreeSet::new()).min(), Some(&1));
|
||||
assert_eq!(a.symmetric_difference(&BTreeSet::new()).max(), Some(&2));
|
||||
assert_eq!(a.union(&a).min(), Some(&1));
|
||||
assert_eq!(a.union(&a).max(), Some(&2));
|
||||
}
|
||||
|
||||
fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F)
|
||||
where
|
||||
F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, &mut dyn FnMut(&i32) -> bool) -> bool,
|
||||
|
|
|
|||
|
|
@ -1801,6 +1801,21 @@ impl<T: Clone> SpecFromElem for T {
|
|||
}
|
||||
}
|
||||
|
||||
impl SpecFromElem for i8 {
|
||||
#[inline]
|
||||
fn from_elem(elem: i8, n: usize) -> Vec<i8> {
|
||||
if elem == 0 {
|
||||
return Vec { buf: RawVec::with_capacity_zeroed(n), len: n };
|
||||
}
|
||||
unsafe {
|
||||
let mut v = Vec::with_capacity(n);
|
||||
ptr::write_bytes(v.as_mut_ptr(), elem as u8, n);
|
||||
v.set_len(n);
|
||||
v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SpecFromElem for u8 {
|
||||
#[inline]
|
||||
fn from_elem(elem: u8, n: usize) -> Vec<u8> {
|
||||
|
|
@ -1845,7 +1860,6 @@ macro_rules! impl_is_zero {
|
|||
};
|
||||
}
|
||||
|
||||
impl_is_zero!(i8, |x| x == 0);
|
||||
impl_is_zero!(i16, |x| x == 0);
|
||||
impl_is_zero!(i32, |x| x == 0);
|
||||
impl_is_zero!(i64, |x| x == 0);
|
||||
|
|
|
|||
|
|
@ -358,12 +358,13 @@ pub fn size_of_val<T: ?Sized>(val: &T) -> usize {
|
|||
/// - an (unstable) [extern type], then this function is always safe to
|
||||
/// call, but may panic or otherwise return the wrong value, as the
|
||||
/// extern type's layout is not known. This is the same behavior as
|
||||
/// [`size_of_val`] on a reference to an extern type tail.
|
||||
/// [`size_of_val`] on a reference to a type with an extern type tail.
|
||||
/// - otherwise, it is conservatively not allowed to call this function.
|
||||
///
|
||||
/// [slice]: ../../std/primitive.slice.html
|
||||
/// [trait object]: ../../book/ch17-02-trait-objects.html
|
||||
/// [extern type]: ../../unstable-book/language-features/extern-types.html
|
||||
/// [`size_of_val`]: ../../core/mem/fn.size_of_val.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
@ -492,12 +493,13 @@ pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
|
|||
/// - an (unstable) [extern type], then this function is always safe to
|
||||
/// call, but may panic or otherwise return the wrong value, as the
|
||||
/// extern type's layout is not known. This is the same behavior as
|
||||
/// [`align_of_val`] on a reference to an extern type tail.
|
||||
/// [`align_of_val`] on a reference to a type with an extern type tail.
|
||||
/// - otherwise, it is conservatively not allowed to call this function.
|
||||
///
|
||||
/// [slice]: ../../std/primitive.slice.html
|
||||
/// [trait object]: ../../book/ch17-02-trait-objects.html
|
||||
/// [extern type]: ../../unstable-book/language-features/extern-types.html
|
||||
/// [`align_of_val`]: ../../core/mem/fn.align_of_val.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
|||
|
|
@ -142,11 +142,6 @@ use crate::{
|
|||
ops::{self, Deref, DerefMut},
|
||||
};
|
||||
|
||||
// Note that this is not a lang item per se, but it has a hidden dependency on
|
||||
// `Iterator`, which is one. The compiler assumes that the `next` method of
|
||||
// `Iterator` is an enumeration with one type parameter and two variants,
|
||||
// which basically means it must be `Option`.
|
||||
|
||||
/// The `Option` type. See [the module level documentation](index.html) for more.
|
||||
#[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
|
||||
#[rustc_diagnostic_item = "option_type"]
|
||||
|
|
|
|||
|
|
@ -617,12 +617,22 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
|
|||
a: &Self,
|
||||
b: &Self,
|
||||
) -> RelateResult<'tcx, Self> {
|
||||
if a.len() != b.len() {
|
||||
let tcx = relation.tcx();
|
||||
|
||||
// FIXME: this is wasteful, but want to do a perf run to see how slow it is.
|
||||
// We need to perform this deduplication as we sometimes generate duplicate projections
|
||||
// in `a`.
|
||||
let mut a_v: Vec<_> = a.into_iter().collect();
|
||||
let mut b_v: Vec<_> = b.into_iter().collect();
|
||||
a_v.sort_by(|a, b| a.stable_cmp(tcx, b));
|
||||
a_v.dedup();
|
||||
b_v.sort_by(|a, b| a.stable_cmp(tcx, b));
|
||||
b_v.dedup();
|
||||
if a_v.len() != b_v.len() {
|
||||
return Err(TypeError::ExistentialMismatch(expected_found(relation, a, b)));
|
||||
}
|
||||
|
||||
let tcx = relation.tcx();
|
||||
let v = a.iter().zip(b.iter()).map(|(ep_a, ep_b)| {
|
||||
let v = a_v.into_iter().zip(b_v.into_iter()).map(|(ep_a, ep_b)| {
|
||||
use crate::ty::ExistentialPredicate::*;
|
||||
match (ep_a, ep_b) {
|
||||
(Trait(ref a), Trait(ref b)) => Ok(Trait(relation.relate(a, b)?)),
|
||||
|
|
|
|||
|
|
@ -350,14 +350,20 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
}
|
||||
|
||||
fn get_const(&self, place: Place<'tcx>) -> Option<OpTy<'tcx>> {
|
||||
let op = self.ecx.eval_place_to_op(place, None).ok();
|
||||
let op = match self.ecx.eval_place_to_op(place, None) {
|
||||
Ok(op) => op,
|
||||
Err(e) => {
|
||||
trace!("get_const failed: {}", e);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
// Try to read the local as an immediate so that if it is representable as a scalar, we can
|
||||
// handle it as such, but otherwise, just return the value as is.
|
||||
match op.map(|ret| self.ecx.try_read_immediate(ret)) {
|
||||
Some(Ok(Ok(imm))) => Some(imm.into()),
|
||||
Some(match self.ecx.try_read_immediate(op) {
|
||||
Ok(Ok(imm)) => imm.into(),
|
||||
_ => op,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Remove `local` from the pool of `Locals`. Allows writing to them,
|
||||
|
|
@ -872,8 +878,9 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
|
|||
if let Ok(place_layout) = self.tcx.layout_of(self.param_env.and(place_ty)) {
|
||||
let can_const_prop = self.can_const_prop[place.local];
|
||||
if let Some(()) = self.const_prop(rval, place_layout, source_info, place) {
|
||||
// This will return None for variables that are from other blocks,
|
||||
// so it should be okay to propagate from here on down.
|
||||
// This will return None if the above `const_prop` invocation only "wrote" a
|
||||
// type whose creation requires no write. E.g. a generator whose initial state
|
||||
// consists solely of uninitialized memory (so it doesn't capture any locals).
|
||||
if let Some(value) = self.get_const(place) {
|
||||
if self.should_const_prop(value) {
|
||||
trace!("replacing {:?} with {:?}", rval, value);
|
||||
|
|
|
|||
|
|
@ -48,8 +48,10 @@ pub fn target() -> Result<Target, String> {
|
|||
"ENCLAVE_SIZE",
|
||||
"CFGDATA_BASE",
|
||||
"DEBUG",
|
||||
"EH_FRM_HDR_BASE",
|
||||
"EH_FRM_HDR_SIZE",
|
||||
"EH_FRM_HDR_OFFSET",
|
||||
"EH_FRM_HDR_LEN",
|
||||
"EH_FRM_OFFSET",
|
||||
"EH_FRM_LEN",
|
||||
"TEXT_BASE",
|
||||
"TEXT_SIZE",
|
||||
];
|
||||
|
|
|
|||
|
|
@ -123,10 +123,6 @@ pub struct Options {
|
|||
///
|
||||
/// Be aware: This option can come both from the CLI and from crate attributes!
|
||||
pub default_passes: DefaultPassOption,
|
||||
/// Document items that have lower than `pub` visibility.
|
||||
pub document_private: bool,
|
||||
/// Document items that have `doc(hidden)`.
|
||||
pub document_hidden: bool,
|
||||
/// Any passes manually selected by the user.
|
||||
///
|
||||
/// Be aware: This option can come both from the CLI and from crate attributes!
|
||||
|
|
@ -177,8 +173,6 @@ impl fmt::Debug for Options {
|
|||
.field("test_args", &self.test_args)
|
||||
.field("persist_doctests", &self.persist_doctests)
|
||||
.field("default_passes", &self.default_passes)
|
||||
.field("document_private", &self.document_private)
|
||||
.field("document_hidden", &self.document_hidden)
|
||||
.field("manual_passes", &self.manual_passes)
|
||||
.field("display_warnings", &self.display_warnings)
|
||||
.field("show_coverage", &self.show_coverage)
|
||||
|
|
@ -250,6 +244,10 @@ pub struct RenderOptions {
|
|||
pub generate_search_filter: bool,
|
||||
/// Option (disabled by default) to generate files used by RLS and some other tools.
|
||||
pub generate_redirect_pages: bool,
|
||||
/// Document items that have lower than `pub` visibility.
|
||||
pub document_private: bool,
|
||||
/// Document items that have `doc(hidden)`.
|
||||
pub document_hidden: bool,
|
||||
}
|
||||
|
||||
impl Options {
|
||||
|
|
@ -567,8 +565,6 @@ impl Options {
|
|||
should_test,
|
||||
test_args,
|
||||
default_passes,
|
||||
document_private,
|
||||
document_hidden,
|
||||
manual_passes,
|
||||
display_warnings,
|
||||
show_coverage,
|
||||
|
|
@ -597,6 +593,8 @@ impl Options {
|
|||
markdown_playground_url,
|
||||
generate_search_filter,
|
||||
generate_redirect_pages,
|
||||
document_private,
|
||||
document_hidden,
|
||||
},
|
||||
output_format,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ pub struct DocContext<'tcx> {
|
|||
// FIXME(eddyb) make this a `ty::TraitRef<'tcx>` set.
|
||||
pub generated_synthetics: RefCell<FxHashSet<(Ty<'tcx>, DefId)>>,
|
||||
pub auto_traits: Vec<DefId>,
|
||||
/// The options given to rustdoc that could be relevant to a pass.
|
||||
pub render_options: RenderOptions,
|
||||
}
|
||||
|
||||
impl<'tcx> DocContext<'tcx> {
|
||||
|
|
@ -281,8 +283,6 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
|
|||
describe_lints,
|
||||
lint_cap,
|
||||
mut default_passes,
|
||||
mut document_private,
|
||||
document_hidden,
|
||||
mut manual_passes,
|
||||
display_warnings,
|
||||
render_options,
|
||||
|
|
@ -448,6 +448,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
|
|||
.cloned()
|
||||
.filter(|trait_def_id| tcx.trait_is_auto(*trait_def_id))
|
||||
.collect(),
|
||||
render_options,
|
||||
};
|
||||
debug!("crate: {:?}", tcx.hir().krate());
|
||||
|
||||
|
|
@ -524,7 +525,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
|
|||
}
|
||||
|
||||
if attr.is_word() && name == sym::document_private_items {
|
||||
document_private = true;
|
||||
ctxt.render_options.document_private = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -544,9 +545,9 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
|
|||
for p in passes {
|
||||
let run = match p.condition {
|
||||
Always => true,
|
||||
WhenDocumentPrivate => document_private,
|
||||
WhenNotDocumentPrivate => !document_private,
|
||||
WhenNotDocumentHidden => !document_hidden,
|
||||
WhenDocumentPrivate => ctxt.render_options.document_private,
|
||||
WhenNotDocumentPrivate => !ctxt.render_options.document_private,
|
||||
WhenNotDocumentHidden => !ctxt.render_options.document_hidden,
|
||||
};
|
||||
if run {
|
||||
debug!("running pass {}", p.pass.name);
|
||||
|
|
@ -556,7 +557,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
|
|||
|
||||
ctxt.sess().abort_if_errors();
|
||||
|
||||
(krate, ctxt.renderinfo.into_inner(), render_options)
|
||||
(krate, ctxt.renderinfo.into_inner(), ctxt.render_options)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -468,7 +468,7 @@ impl clean::Path {
|
|||
|
||||
pub fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> {
|
||||
let cache = cache();
|
||||
if !did.is_local() && !cache.access_levels.is_public(did) {
|
||||
if !did.is_local() && !cache.access_levels.is_public(did) && !cache.document_private {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -469,6 +469,7 @@ pub fn run(
|
|||
static_root_path,
|
||||
generate_search_filter,
|
||||
generate_redirect_pages,
|
||||
document_private,
|
||||
..
|
||||
} = options;
|
||||
|
||||
|
|
@ -546,7 +547,7 @@ pub fn run(
|
|||
scx.ensure_dir(&dst)?;
|
||||
krate = sources::render(&dst, &mut scx, krate)?;
|
||||
let (new_crate, index, cache) =
|
||||
Cache::from_krate(renderinfo, &extern_html_root_urls, &dst, krate);
|
||||
Cache::from_krate(renderinfo, document_private, &extern_html_root_urls, &dst, krate);
|
||||
krate = new_crate;
|
||||
let cache = Arc::new(cache);
|
||||
let mut cx = Context {
|
||||
|
|
|
|||
|
|
@ -91,6 +91,10 @@ crate struct Cache {
|
|||
/// The version of the crate being documented, if given from the `--crate-version` flag.
|
||||
pub crate_version: Option<String>,
|
||||
|
||||
/// Whether to document private items.
|
||||
/// This is stored in `Cache` so it doesn't need to be passed through all rustdoc functions.
|
||||
pub document_private: bool,
|
||||
|
||||
// Private fields only used when initially crawling a crate to build a cache
|
||||
stack: Vec<String>,
|
||||
parent_stack: Vec<DefId>,
|
||||
|
|
@ -126,6 +130,7 @@ crate struct Cache {
|
|||
impl Cache {
|
||||
pub fn from_krate(
|
||||
renderinfo: RenderInfo,
|
||||
document_private: bool,
|
||||
extern_html_root_urls: &BTreeMap<String, String>,
|
||||
dst: &Path,
|
||||
mut krate: clean::Crate,
|
||||
|
|
@ -160,6 +165,7 @@ impl Cache {
|
|||
stripped_mod: false,
|
||||
access_levels,
|
||||
crate_version: krate.version.take(),
|
||||
document_private,
|
||||
orphan_impl_items: Vec::new(),
|
||||
orphan_trait_impls: Vec::new(),
|
||||
traits: krate.external_traits.replace(Default::default()),
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
let result = cx.enter_resolver(|resolver| {
|
||||
resolver.resolve_str_path_error(DUMMY_SP, &path_str, ns, module_id)
|
||||
});
|
||||
debug!("{} resolved to {:?} in namespace {:?}", path_str, result, ns);
|
||||
let result = match result {
|
||||
Ok((_, Res::Err)) => Err(ErrorKind::ResolutionFailure),
|
||||
_ => result.map_err(|_| ErrorKind::ResolutionFailure),
|
||||
|
|
@ -202,7 +203,13 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
}
|
||||
return Ok((res, Some(path_str.to_owned())));
|
||||
}
|
||||
_ => return Ok((res, extra_fragment.clone())),
|
||||
other => {
|
||||
debug!(
|
||||
"failed to resolve {} in namespace {:?} (got {:?})",
|
||||
path_str, ns, other
|
||||
);
|
||||
return Ok((res, extra_fragment.clone()));
|
||||
}
|
||||
};
|
||||
|
||||
if value != (ns == ValueNS) {
|
||||
|
|
@ -555,12 +562,13 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
|||
} else {
|
||||
(parts[0].to_owned(), None)
|
||||
};
|
||||
let resolved_self;
|
||||
let mut path_str;
|
||||
let (res, fragment) = {
|
||||
let mut kind = None;
|
||||
let mut path_str = if let Some(prefix) =
|
||||
["struct@", "enum@", "type@", "trait@", "union@"]
|
||||
.iter()
|
||||
.find(|p| link.starts_with(**p))
|
||||
path_str = if let Some(prefix) = ["struct@", "enum@", "type@", "trait@", "union@"]
|
||||
.iter()
|
||||
.find(|p| link.starts_with(**p))
|
||||
{
|
||||
kind = Some(TypeNS);
|
||||
link.trim_start_matches(prefix)
|
||||
|
|
@ -614,7 +622,6 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
|||
let base_node =
|
||||
if item.is_mod() && item.attrs.inner_docs { None } else { parent_node };
|
||||
|
||||
let resolved_self;
|
||||
// replace `Self` with suitable item's parent name
|
||||
if path_str.starts_with("Self::") {
|
||||
if let Some(ref name) = parent_name {
|
||||
|
|
@ -760,6 +767,32 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
|||
if let Res::PrimTy(_) = res {
|
||||
item.attrs.links.push((ori_link, None, fragment));
|
||||
} else {
|
||||
debug!("intra-doc link to {} resolved to {:?}", path_str, res);
|
||||
if let Some(local) = res.opt_def_id().and_then(|def_id| def_id.as_local()) {
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
|
||||
let hir_id = self.cx.tcx.hir().as_local_hir_id(local);
|
||||
if !self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_id)
|
||||
&& !self.cx.render_options.document_private
|
||||
{
|
||||
let item_name = item.name.as_deref().unwrap_or("<unknown>");
|
||||
let err_msg = format!(
|
||||
"public documentation for `{}` links to a private item",
|
||||
item_name
|
||||
);
|
||||
build_diagnostic(
|
||||
cx,
|
||||
&item,
|
||||
path_str,
|
||||
&dox,
|
||||
link_range,
|
||||
&err_msg,
|
||||
"this item is private",
|
||||
None,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let id = register_res(cx, res);
|
||||
item.attrs.links.push((ori_link, Some(id), fragment));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1217,11 +1217,66 @@ mod self_keyword {}
|
|||
/// The implementing type within a [`trait`] or [`impl`] block, or the current type within a type
|
||||
/// definition.
|
||||
///
|
||||
/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
|
||||
/// Within a type definition:
|
||||
///
|
||||
/// ```
|
||||
/// # #![allow(dead_code)]
|
||||
/// struct Node {
|
||||
/// elem: i32,
|
||||
/// // `Self` is a `Node` here.
|
||||
/// next: Option<Box<Self>>,
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// In an [`impl`] block:
|
||||
///
|
||||
/// ```
|
||||
/// struct Foo(i32);
|
||||
///
|
||||
/// impl Foo {
|
||||
/// fn new() -> Self {
|
||||
/// Self(0)
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(Foo::new().0, Foo(0).0);
|
||||
/// ```
|
||||
///
|
||||
/// Generic parameters are implicit with `Self`:
|
||||
///
|
||||
/// ```
|
||||
/// # #![allow(dead_code)]
|
||||
/// struct Wrap<T> {
|
||||
/// elem: T,
|
||||
/// }
|
||||
///
|
||||
/// impl<T> Wrap<T> {
|
||||
/// fn new(elem: T) -> Self {
|
||||
/// Self { elem }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// In a [`trait`] definition and related [`impl`] block:
|
||||
///
|
||||
/// ```
|
||||
/// trait Example {
|
||||
/// fn example() -> Self;
|
||||
/// }
|
||||
///
|
||||
/// struct Foo(i32);
|
||||
///
|
||||
/// impl Example for Foo {
|
||||
/// fn example() -> Self {
|
||||
/// Self(42)
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(Foo::example().0, Foo(42).0);
|
||||
/// ```
|
||||
///
|
||||
/// [`impl`]: keyword.impl.html
|
||||
/// [`trait`]: keyword.trait.html
|
||||
/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
|
||||
mod self_upper_keyword {}
|
||||
|
||||
#[doc(keyword = "static")]
|
||||
|
|
@ -1345,10 +1400,26 @@ mod struct_keyword {}
|
|||
//
|
||||
/// The parent of the current [module].
|
||||
///
|
||||
/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
|
||||
/// ```rust
|
||||
/// # #![allow(dead_code)]
|
||||
/// # fn main() {}
|
||||
/// mod a {
|
||||
/// pub fn foo() {}
|
||||
/// }
|
||||
/// mod b {
|
||||
/// pub fn foo() {
|
||||
/// super::a::foo(); // call a's foo function
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// It is also possible to use `super` multiple times: `super::super::foo`,
|
||||
/// going up the ancestor chain.
|
||||
///
|
||||
/// See the [Reference] for more information.
|
||||
///
|
||||
/// [module]: ../reference/items/modules.html
|
||||
/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
|
||||
/// [Reference]: ../reference/paths.html#super
|
||||
mod super_keyword {}
|
||||
|
||||
#[doc(keyword = "trait")]
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ IMAGE_BASE:
|
|||
.long 1 /* type = NT_VERSION */
|
||||
0: .asciz "toolchain-version" /* name */
|
||||
1: .align 4
|
||||
2: .long 0 /* desc - toolchain version number, 32-bit LE */
|
||||
2: .long 1 /* desc - toolchain version number, 32-bit LE */
|
||||
3: .align 4
|
||||
|
||||
.section .rodata
|
||||
|
|
@ -60,10 +60,14 @@ IMAGE_BASE:
|
|||
globvar TEXT_BASE 8
|
||||
/* The size in bytes of enclacve text section */
|
||||
globvar TEXT_SIZE 8
|
||||
/* The base address (relative to enclave start) of the enclave EH_FRM_HDR section */
|
||||
globvar EH_FRM_HDR_BASE 8
|
||||
/* The size in bytes of enclacve EH_FRM_HDR section */
|
||||
globvar EH_FRM_HDR_SIZE 8
|
||||
/* The base address (relative to enclave start) of the enclave .eh_frame_hdr section */
|
||||
globvar EH_FRM_HDR_OFFSET 8
|
||||
/* The size in bytes of enclave .eh_frame_hdr section */
|
||||
globvar EH_FRM_HDR_LEN 8
|
||||
/* The base address (relative to enclave start) of the enclave .eh_frame section */
|
||||
globvar EH_FRM_OFFSET 8
|
||||
/* The size in bytes of enclacve .eh_frame section */
|
||||
globvar EH_FRM_LEN 8
|
||||
|
||||
.org .Lxsave_clear+512
|
||||
.Lxsave_header:
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ fn main() {
|
|||
{
|
||||
// Build the unwinding from libunwind C/C++ source code.
|
||||
llvm_libunwind::compile();
|
||||
} else if target.contains("x86_64-fortanix-unknown-sgx") {
|
||||
llvm_libunwind::compile();
|
||||
} else if target.contains("linux") {
|
||||
if target.contains("musl") {
|
||||
// linking for musl is handled in lib.rs
|
||||
|
|
@ -55,6 +57,7 @@ mod llvm_libunwind {
|
|||
|
||||
/// Compile the libunwind C/C++ source code.
|
||||
pub fn compile() {
|
||||
let target = env::var("TARGET").expect("TARGET was not set");
|
||||
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
|
||||
let target_vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap();
|
||||
let target_endian_little = env::var("CARGO_CFG_TARGET_ENDIAN").unwrap() != "big";
|
||||
|
|
@ -75,6 +78,35 @@ mod llvm_libunwind {
|
|||
cfg.flag("/EHsc");
|
||||
cfg.define("_CRT_SECURE_NO_WARNINGS", None);
|
||||
cfg.define("_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS", None);
|
||||
} else if target.contains("x86_64-fortanix-unknown-sgx") {
|
||||
cfg.cpp(false);
|
||||
|
||||
cfg.static_flag(true);
|
||||
cfg.opt_level(3);
|
||||
|
||||
cfg.flag("-nostdinc++");
|
||||
cfg.flag("-fno-exceptions");
|
||||
cfg.flag("-fno-rtti");
|
||||
cfg.flag("-fstrict-aliasing");
|
||||
cfg.flag("-funwind-tables");
|
||||
cfg.flag("-fvisibility=hidden");
|
||||
cfg.flag("-fno-stack-protector");
|
||||
cfg.flag("-ffreestanding");
|
||||
cfg.flag("-fexceptions");
|
||||
|
||||
// easiest way to undefine since no API available in cc::Build to undefine
|
||||
cfg.flag("-U_FORTIFY_SOURCE");
|
||||
cfg.define("_FORTIFY_SOURCE", "0");
|
||||
|
||||
cfg.flag_if_supported("-fvisibility-global-new-delete-hidden");
|
||||
|
||||
cfg.define("_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS", None);
|
||||
cfg.define("RUST_SGX", "1");
|
||||
cfg.define("__NO_STRING_INLINES", None);
|
||||
cfg.define("__NO_MATH_INLINES", None);
|
||||
cfg.define("_LIBUNWIND_IS_BAREMETAL", None);
|
||||
cfg.define("__LIBUNWIND_IS_NATIVE_ONLY", None);
|
||||
cfg.define("NDEBUG", None);
|
||||
} else {
|
||||
cfg.flag("-std=c99");
|
||||
cfg.flag("-std=c++11");
|
||||
|
|
@ -103,6 +135,10 @@ mod llvm_libunwind {
|
|||
unwind_sources.push("Unwind_AppleExtras.cpp");
|
||||
}
|
||||
|
||||
if target.contains("x86_64-fortanix-unknown-sgx") {
|
||||
unwind_sources.push("UnwindRustSgx.c");
|
||||
}
|
||||
|
||||
let root = Path::new("../llvm-project/libunwind");
|
||||
cfg.include(root.join("include"));
|
||||
for src in unwind_sources {
|
||||
|
|
|
|||
10
src/test/rustdoc-ui/intra-links-private.public.stderr
Normal file
10
src/test/rustdoc-ui/intra-links-private.public.stderr
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
warning: `[DontDocMe]` public documentation for `DocMe` links to a private item
|
||||
--> $DIR/intra-links-private.rs:6:11
|
||||
|
|
||||
LL | /// docs [DontDocMe]
|
||||
| ^^^^^^^^^ this item is private
|
||||
|
|
||||
= note: `#[warn(intra_doc_link_resolution_failure)]` on by default
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
10
src/test/rustdoc-ui/intra-links-private.rs
Normal file
10
src/test/rustdoc-ui/intra-links-private.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
// check-pass
|
||||
// revisions: public private
|
||||
// [private]compile-flags: --document-private-items
|
||||
#![cfg_attr(private, deny(intra_doc_resolution_failure))]
|
||||
|
||||
/// docs [DontDocMe]
|
||||
//[public]~^ WARNING `[DontDocMe]` public documentation for `DocMe` links to a private item
|
||||
// FIXME: for [private] we should also make sure the link was actually generated
|
||||
pub struct DocMe;
|
||||
struct DontDocMe;
|
||||
6
src/test/rustdoc-ui/reference-link-has-one-warning.rs
Normal file
6
src/test/rustdoc-ui/reference-link-has-one-warning.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
// ignore-test
|
||||
// check-pass
|
||||
|
||||
/// docs [label][with#anchor#error]
|
||||
//~^ WARNING has an issue with the link anchor
|
||||
pub struct S;
|
||||
10
src/test/rustdoc-ui/reference-link-has-one-warning.stderr
Normal file
10
src/test/rustdoc-ui/reference-link-has-one-warning.stderr
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
warning: `[with#anchor#error]` has an issue with the link anchor.
|
||||
--> $DIR/reference-link-has-one-warning.rs:3:18
|
||||
|
|
||||
LL | /// docs [label][with#anchor#error]
|
||||
| ^^^^^^^^^^^^^^^^^ only one `#` is allowed in a link
|
||||
|
|
||||
= note: `#[warn(intra_doc_link_resolution_failure)]` on by default
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
26
src/test/ui/issues/issue-59326.rs
Normal file
26
src/test/ui/issues/issue-59326.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// check-pass
|
||||
trait Service {
|
||||
type S;
|
||||
}
|
||||
|
||||
trait Framing {
|
||||
type F;
|
||||
}
|
||||
|
||||
impl Framing for () {
|
||||
type F = ();
|
||||
}
|
||||
|
||||
trait HttpService<F: Framing>: Service<S = F::F> {}
|
||||
|
||||
type BoxService = Box<dyn HttpService<(), S = ()>>;
|
||||
|
||||
fn build_server<F: FnOnce() -> BoxService>(_: F) {}
|
||||
|
||||
fn make_server<F: Framing>() -> Box<dyn HttpService<F, S = F::F>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
build_server(|| make_server())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue