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:
bors 2020-06-27 02:44:35 +00:00
commit 394e1b40d2
29 changed files with 445 additions and 116 deletions

View file

@ -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)

View file

@ -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 {

View file

@ -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.

View file

@ -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

View file

@ -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> {

View file

@ -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")]

View file

@ -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

View file

@ -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)| {

View file

@ -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,

View file

@ -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);

View file

@ -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
///

View file

@ -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"]

View file

@ -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)?)),

View file

@ -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);

View file

@ -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",
];

View file

@ -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,
})

View file

@ -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)
})
})
})

View file

@ -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;
}

View file

@ -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 {

View file

@ -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()),

View file

@ -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));
}

View file

@ -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")]

View file

@ -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:

View file

@ -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 {

View 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

View 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;

View 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;

View 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

View 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())
}