Auto merge of #93021 - matthiaskrgr:rollup-o7z8zoe, r=matthiaskrgr

Rollup of 14 pull requests

Successful merges:

 - #92629 (Pick themes on settings page, not every page)
 - #92640 (Fix ICEs related to `Deref<Target=[T; N]>` on newtypes)
 - #92701 (Add some more attribute validation)
 - #92803 (Hide mobile sidebar on some clicks)
 - #92830 (Rustdoc style cleanups)
 - #92866 ("Does exists" typos fix)
 - #92870 (add `rustc_diagnostic_item` attribute to `AtomicBool` type)
 - #92914 (htmldocck: Add support for `/text()` in ``@snapshot`)`
 - #92923 (Abstract the pretty printer's ringbuffer to be infinitely sized)
 - #92946 (Exclude llvm-libunwind from the self-contained set on s390x-musl targets)
 - #92947 (rustdoc: Use `intersperse` in a `visit_path` function)
 - #92997 (Add `~const` bound test for negative impls)
 - #93004 (update codegen test for LLVM 14)
 - #93016 (Stabilize vec_spare_capacity)

Failed merges:

 - #92924 (Delete pretty printer tracing)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-01-18 06:07:58 +00:00
commit 7531d2fdd4
46 changed files with 687 additions and 310 deletions

View file

@ -132,6 +132,9 @@
//! methods called `Printer::scan_*`, and the 'PRINT' process is the
//! method called `Printer::print`.
mod ring;
use ring::RingBuffer;
use std::borrow::Cow;
use std::collections::VecDeque;
use std::fmt;
@ -190,8 +193,7 @@ impl fmt::Display for Token {
}
}
fn buf_str(buf: &[BufEntry], left: usize, right: usize, lim: usize) -> String {
let n = buf.len();
fn buf_str(buf: &RingBuffer<BufEntry>, left: usize, right: usize, lim: usize) -> String {
let mut i = left;
let mut l = lim;
let mut s = String::from("[");
@ -202,7 +204,6 @@ fn buf_str(buf: &[BufEntry], left: usize, right: usize, lim: usize) -> String {
}
s.push_str(&format!("{}={}", buf[i].size, &buf[i].token));
i += 1;
i %= n;
}
s.push(']');
s
@ -224,7 +225,6 @@ const SIZE_INFINITY: isize = 0xffff;
pub struct Printer {
out: String,
buf_max_len: usize,
/// Width of lines we're constrained to
margin: isize,
/// Number of spaces left on line
@ -234,7 +234,7 @@ pub struct Printer {
/// Index of right side of input stream
right: usize,
/// Ring-buffer of tokens and calculated sizes
buf: Vec<BufEntry>,
buf: RingBuffer<BufEntry>,
/// Running size of stream "...left"
left_total: isize,
/// Running size of stream "...right"
@ -267,19 +267,16 @@ impl Default for BufEntry {
impl Printer {
pub fn new() -> Self {
let linewidth = 78;
// Yes 55, it makes the ring buffers big enough to never fall behind.
let n: usize = 55 * linewidth;
debug!("Printer::new {}", linewidth);
let mut buf = RingBuffer::new();
buf.advance_right();
Printer {
out: String::new(),
buf_max_len: n,
margin: linewidth as isize,
space: linewidth as isize,
left: 0,
right: 0,
// Initialize a single entry; advance_right() will extend it on demand
// up to `buf_max_len` elements.
buf: vec![BufEntry::default()],
buf,
left_total: 0,
right_total: 0,
scan_stack: VecDeque::new(),
@ -308,8 +305,8 @@ impl Printer {
if self.scan_stack.is_empty() {
self.left_total = 1;
self.right_total = 1;
self.left = 0;
self.right = 0;
self.right = self.left;
self.buf.truncate(1);
} else {
self.advance_right();
}
@ -332,8 +329,8 @@ impl Printer {
if self.scan_stack.is_empty() {
self.left_total = 1;
self.right_total = 1;
self.left = 0;
self.right = 0;
self.right = self.left;
self.buf.truncate(1);
} else {
self.advance_right();
}
@ -400,12 +397,7 @@ impl Printer {
fn advance_right(&mut self) {
self.right += 1;
self.right %= self.buf_max_len;
// Extend the buf if necessary.
if self.right == self.buf.len() {
self.buf.push(BufEntry::default());
}
assert_ne!(self.right, self.left);
self.buf.advance_right();
}
fn advance_left(&mut self) {
@ -437,8 +429,8 @@ impl Printer {
break;
}
self.buf.advance_left();
self.left += 1;
self.left %= self.buf_max_len;
left_size = self.buf[self.left].size;
}

View file

@ -0,0 +1,53 @@
use std::collections::VecDeque;
use std::ops::{Index, IndexMut};
/// A view onto a finite range of an infinitely long sequence of T.
///
/// The Ts are indexed 0..infinity. A RingBuffer begins as a view of elements
/// 0..0 (i.e. nothing). The user of the RingBuffer advances its left and right
/// position independently, although only in the positive direction, and only
/// with left <= right at all times.
///
/// Holding a RingBuffer whose view is elements left..right gives the ability to
/// use Index and IndexMut to access elements i in the infinitely long queue for
/// which left <= i < right.
pub struct RingBuffer<T> {
data: VecDeque<T>,
// Abstract index of data[0] in the infinitely sized queue.
offset: usize,
}
impl<T> RingBuffer<T> {
pub fn new() -> Self {
RingBuffer { data: VecDeque::new(), offset: 0 }
}
pub fn advance_right(&mut self)
where
T: Default,
{
self.data.push_back(T::default());
}
pub fn advance_left(&mut self) {
self.data.pop_front().unwrap();
self.offset += 1;
}
pub fn truncate(&mut self, len: usize) {
self.data.truncate(len);
}
}
impl<T> Index<usize> for RingBuffer<T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self.data[index.checked_sub(self.offset).unwrap()]
}
}
impl<T> IndexMut<usize> for RingBuffer<T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.data[index.checked_sub(self.offset).unwrap()]
}
}

View file

@ -352,7 +352,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
// Runtime
ungated!(
windows_subsystem, Normal,
windows_subsystem, CrateLevel,
template!(NameValueStr: "windows|console"), FutureWarnFollowing
),
ungated!(panic_handler, Normal, template!(Word), WarnFollowing), // RFC 2070
@ -360,7 +360,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
// Code generation:
ungated!(inline, Normal, template!(Word, List: "always|never"), FutureWarnFollowing),
ungated!(cold, Normal, template!(Word), WarnFollowing),
ungated!(no_builtins, Normal, template!(Word), WarnFollowing),
ungated!(no_builtins, CrateLevel, template!(Word), WarnFollowing),
ungated!(target_feature, Normal, template!(List: r#"enable = "name""#), DuplicatesOk),
ungated!(track_caller, Normal, template!(Word), WarnFollowing),
gated!(

View file

@ -425,7 +425,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
// FIXME: perf problem described in #55921.
ui = ty::UniverseIndex::ROOT;
return self.canonicalize_const_var(
CanonicalVarInfo { kind: CanonicalVarKind::Const(ui) },
CanonicalVarInfo { kind: CanonicalVarKind::Const(ui, ct.ty) },
ct,
);
}

View file

@ -137,12 +137,9 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
self.tcx.mk_region(ty::RePlaceholder(placeholder_mapped)).into()
}
CanonicalVarKind::Const(ui) => self
CanonicalVarKind::Const(ui, ty) => self
.next_const_var_in_universe(
self.next_ty_var_in_universe(
TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span },
universe_map(ui),
),
ty,
ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span },
universe_map(ui),
)

View file

@ -23,7 +23,7 @@
use crate::infer::MemberConstraint;
use crate::ty::subst::GenericArg;
use crate::ty::{self, BoundVar, List, Region, TyCtxt};
use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt};
use rustc_index::vec::IndexVec;
use rustc_macros::HashStable;
use smallvec::SmallVec;
@ -104,7 +104,7 @@ impl<'tcx> CanonicalVarInfo<'tcx> {
CanonicalVarKind::PlaceholderTy(_) => false,
CanonicalVarKind::Region(_) => true,
CanonicalVarKind::PlaceholderRegion(..) => false,
CanonicalVarKind::Const(_) => true,
CanonicalVarKind::Const(..) => true,
CanonicalVarKind::PlaceholderConst(_) => false,
}
}
@ -130,7 +130,7 @@ pub enum CanonicalVarKind<'tcx> {
PlaceholderRegion(ty::PlaceholderRegion),
/// Some kind of const inference variable.
Const(ty::UniverseIndex),
Const(ty::UniverseIndex, Ty<'tcx>),
/// A "placeholder" that represents "any const".
PlaceholderConst(ty::PlaceholderConst<'tcx>),
@ -147,7 +147,7 @@ impl<'tcx> CanonicalVarKind<'tcx> {
CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe,
CanonicalVarKind::Region(ui) => ui,
CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe,
CanonicalVarKind::Const(ui) => ui,
CanonicalVarKind::Const(ui, _) => ui,
CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.universe,
}
}

View file

@ -126,6 +126,7 @@ impl CheckAttrVisitor<'_> {
// lint-only checks
match attr.name_or_empty() {
sym::cold => self.check_cold(hir_id, attr, span, target),
sym::link => self.check_link(hir_id, attr, span, target),
sym::link_name => self.check_link_name(hir_id, attr, span, target),
sym::link_section => self.check_link_section(hir_id, attr, span, target),
sym::no_mangle => self.check_no_mangle(hir_id, attr, span, target),
@ -1157,6 +1158,26 @@ impl CheckAttrVisitor<'_> {
}
}
/// Checks if `#[link]` is applied to an item other than a foreign module.
fn check_link(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) {
match target {
Target::ForeignMod => {}
_ => {
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
let mut diag = lint.build("attribute should be applied to an `extern` block");
diag.warn(
"this was previously accepted by the compiler but is \
being phased out; it will become a hard error in \
a future release!",
);
diag.span_label(*span, "not an `extern` block");
diag.emit();
});
}
}
}
/// Checks if `#[link_name]` is applied to an item other than a foreign function or static.
fn check_link_name(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) {
match target {

View file

@ -85,7 +85,7 @@ crate fn evaluate_goal<'tcx>(
chalk_ir::VariableKind::Lifetime,
chalk_ir::UniverseIndex { counter: ui.index() },
),
CanonicalVarKind::Const(_ui) => unimplemented!(),
CanonicalVarKind::Const(_ui, _ty) => unimplemented!(),
CanonicalVarKind::PlaceholderConst(_pc) => unimplemented!(),
}),
),
@ -127,9 +127,9 @@ crate fn evaluate_goal<'tcx>(
chalk_ir::VariableKind::Lifetime => CanonicalVarKind::Region(
ty::UniverseIndex::from_usize(var.skip_kind().counter),
),
chalk_ir::VariableKind::Const(_) => CanonicalVarKind::Const(
ty::UniverseIndex::from_usize(var.skip_kind().counter),
),
// FIXME(compiler-errors): We don't currently have a way of turning
// a Chalk ty back into a rustc ty, right?
chalk_ir::VariableKind::Const(_) => todo!(),
};
CanonicalVarInfo { kind }
})

View file

@ -149,7 +149,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
// time writing the results into the various typeck results.
let mut autoderef =
self.autoderef_overloaded_span(self.span, unadjusted_self_ty, self.call_expr.span);
let (_, n) = match autoderef.nth(pick.autoderefs) {
let (ty, n) = match autoderef.nth(pick.autoderefs) {
Some(n) => n,
None => {
return self.tcx.ty_error_with_message(
@ -161,14 +161,15 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
assert_eq!(n, pick.autoderefs);
let mut adjustments = self.adjust_steps(&autoderef);
let mut target = self.structurally_resolved_type(autoderef.span(), ty);
let mut target =
self.structurally_resolved_type(autoderef.span(), autoderef.final_ty(false));
match &pick.autoref_or_ptr_adjustment {
match pick.autoref_or_ptr_adjustment {
Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl, unsize }) => {
let region = self.next_region_var(infer::Autoref(self.span));
target = self.tcx.mk_ref(region, ty::TypeAndMut { mutbl: *mutbl, ty: target });
// Type we're wrapping in a reference, used later for unsizing
let base_ty = target;
target = self.tcx.mk_ref(region, ty::TypeAndMut { mutbl, ty: target });
let mutbl = match mutbl {
hir::Mutability::Not => AutoBorrowMutability::Not,
hir::Mutability::Mut => AutoBorrowMutability::Mut {
@ -182,10 +183,18 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
target,
});
if let Some(unsize_target) = unsize {
if unsize {
let unsized_ty = if let ty::Array(elem_ty, _) = base_ty.kind() {
self.tcx.mk_slice(elem_ty)
} else {
bug!(
"AutorefOrPtrAdjustment's unsize flag should only be set for array ty, found {}",
base_ty
)
};
target = self
.tcx
.mk_ref(region, ty::TypeAndMut { mutbl: mutbl.into(), ty: unsize_target });
.mk_ref(region, ty::TypeAndMut { mutbl: mutbl.into(), ty: unsized_ty });
adjustments
.push(Adjustment { kind: Adjust::Pointer(PointerCast::Unsize), target });
}

View file

@ -167,26 +167,26 @@ enum ProbeResult {
/// T`, we could convert it to `*const T`, then autoref to `&*const T`. However, currently we do
/// (at most) one of these. Either the receiver has type `T` and we convert it to `&T` (or with
/// `mut`), or it has type `*mut T` and we convert it to `*const T`.
#[derive(Debug, PartialEq, Clone)]
pub enum AutorefOrPtrAdjustment<'tcx> {
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum AutorefOrPtrAdjustment {
/// Receiver has type `T`, add `&` or `&mut` (it `T` is `mut`), and maybe also "unsize" it.
/// Unsizing is used to convert a `[T; N]` to `[T]`, which only makes sense when autorefing.
Autoref {
mutbl: hir::Mutability,
/// Indicates that the source expression should be "unsized" to a target type. This should
/// probably eventually go away in favor of just coercing method receivers.
unsize: Option<Ty<'tcx>>,
/// Indicates that the source expression should be "unsized" to a target type.
/// This is special-cased for just arrays unsizing to slices.
unsize: bool,
},
/// Receiver has type `*mut T`, convert to `*const T`
ToConstPtr,
}
impl<'tcx> AutorefOrPtrAdjustment<'tcx> {
fn get_unsize(&self) -> Option<Ty<'tcx>> {
impl AutorefOrPtrAdjustment {
fn get_unsize(&self) -> bool {
match self {
AutorefOrPtrAdjustment::Autoref { mutbl: _, unsize } => *unsize,
AutorefOrPtrAdjustment::ToConstPtr => None,
AutorefOrPtrAdjustment::ToConstPtr => false,
}
}
}
@ -204,7 +204,7 @@ pub struct Pick<'tcx> {
/// Indicates that we want to add an autoref (and maybe also unsize it), or if the receiver is
/// `*mut T`, convert it to `*const T`.
pub autoref_or_ptr_adjustment: Option<AutorefOrPtrAdjustment<'tcx>>,
pub autoref_or_ptr_adjustment: Option<AutorefOrPtrAdjustment>,
pub self_ty: Ty<'tcx>,
}
@ -1202,7 +1202,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
pick.autoderefs += 1;
pick.autoref_or_ptr_adjustment = Some(AutorefOrPtrAdjustment::Autoref {
mutbl,
unsize: pick.autoref_or_ptr_adjustment.and_then(|a| a.get_unsize()),
unsize: pick.autoref_or_ptr_adjustment.map_or(false, |a| a.get_unsize()),
})
}
@ -1227,10 +1227,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
self.pick_method(autoref_ty, unstable_candidates).map(|r| {
r.map(|mut pick| {
pick.autoderefs = step.autoderefs;
pick.autoref_or_ptr_adjustment = Some(AutorefOrPtrAdjustment::Autoref {
mutbl,
unsize: step.unsize.then_some(self_ty),
});
pick.autoref_or_ptr_adjustment =
Some(AutorefOrPtrAdjustment::Autoref { mutbl, unsize: step.unsize });
pick
})
})

View file

@ -2051,8 +2051,6 @@ impl<T, A: Allocator> Vec<T, A> {
/// # Examples
///
/// ```
/// #![feature(vec_spare_capacity)]
///
/// // Allocate vector big enough for 10 elements.
/// let mut v = Vec::with_capacity(10);
///
@ -2069,7 +2067,7 @@ impl<T, A: Allocator> Vec<T, A> {
///
/// assert_eq!(&v, &[0, 1, 2]);
/// ```
#[unstable(feature = "vec_spare_capacity", issue = "75017")]
#[stable(feature = "vec_spare_capacity", since = "1.60.0")]
#[inline]
pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
// Note:

View file

@ -31,7 +31,6 @@
#![feature(iter_advance_by)]
#![feature(slice_group_by)]
#![feature(slice_partition_dedup)]
#![feature(vec_spare_capacity)]
#![feature(string_remove_matches)]
#![feature(const_btree_new)]
#![feature(const_default_impls)]

View file

@ -1038,7 +1038,7 @@ impl<T> MaybeUninit<T> {
/// ```
///
/// ```
/// #![feature(maybe_uninit_write_slice, vec_spare_capacity)]
/// #![feature(maybe_uninit_write_slice)]
/// use std::mem::MaybeUninit;
///
/// let mut vec = Vec::with_capacity(32);
@ -1098,7 +1098,7 @@ impl<T> MaybeUninit<T> {
/// ```
///
/// ```
/// #![feature(maybe_uninit_write_slice, vec_spare_capacity)]
/// #![feature(maybe_uninit_write_slice)]
/// use std::mem::MaybeUninit;
///
/// let mut vec = Vec::with_capacity(32);

View file

@ -131,6 +131,7 @@ use crate::hint::spin_loop;
/// loads and stores of `u8`.
#[cfg(target_has_atomic_load_store = "8")]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "AtomicBool"]
#[repr(C, align(1))]
pub struct AtomicBool {
v: UnsafeCell<u8>,

View file

@ -1050,7 +1050,7 @@ impl Metadata {
///
/// fn main() -> std::io::Result<()> {
/// let link_path = Path::new("link");
/// symlink("/origin_does_not_exists/", link_path)?;
/// symlink("/origin_does_not_exist/", link_path)?;
///
/// let metadata = fs::symlink_metadata(link_path)?;
///

View file

@ -340,7 +340,6 @@
#![feature(unboxed_closures)]
#![feature(unwrap_infallible)]
#![feature(vec_into_raw_parts)]
#![feature(vec_spare_capacity)]
// NB: the above list is sorted to minimize merge conflicts.
#![default_lib_allocator]

View file

@ -2806,7 +2806,7 @@ impl Path {
/// use std::os::unix::fs::symlink;
///
/// let link_path = Path::new("link");
/// symlink("/origin_does_not_exists/", link_path).unwrap();
/// symlink("/origin_does_not_exist/", link_path).unwrap();
/// assert_eq!(link_path.is_symlink(), true);
/// assert_eq!(link_path.exists(), false);
/// ```

@ -1 +1 @@
Subproject commit 2adc17a5442614dbe34626fdd9b32de7c07b8086
Subproject commit 1d5d0e8b0e3134dc781adb98057e38ffdf200df2

View file

@ -863,7 +863,7 @@ class RustBuild(object):
>>> rb.get_toml("key2")
'value2'
If the key does not exists, the result is None:
If the key does not exist, the result is None:
>>> rb.get_toml("key3") is None
True

View file

@ -55,8 +55,8 @@ class ProgramOutOfDate(unittest.TestCase):
def tearDown(self):
rmtree(self.container)
def test_stamp_path_does_not_exists(self):
"""Return True when the stamp file does not exists"""
def test_stamp_path_does_not_exist(self):
"""Return True when the stamp file does not exist"""
if os.path.exists(self.rustc_stamp_path):
os.unlink(self.rustc_stamp_path)
self.assertTrue(self.build.program_out_of_date(self.rustc_stamp_path, self.key))

View file

@ -227,8 +227,10 @@ fn copy_self_contained_objects(
target_deps.push((target, DependencyType::TargetSelfContained));
}
let libunwind_path = copy_llvm_libunwind(builder, target, &libdir_self_contained);
target_deps.push((libunwind_path, DependencyType::TargetSelfContained));
if !target.starts_with("s390x") {
let libunwind_path = copy_llvm_libunwind(builder, target, &libdir_self_contained);
target_deps.push((libunwind_path, DependencyType::TargetSelfContained));
}
} else if target.ends_with("-wasi") {
let srcdir = builder
.wasi_root(target)

View file

@ -401,7 +401,7 @@ def get_tree_count(tree, path):
return len(tree.findall(path))
def check_snapshot(snapshot_name, tree):
def check_snapshot(snapshot_name, tree, normalize_to_text):
assert rust_test_path.endswith('.rs')
snapshot_path = '{}.{}.{}'.format(rust_test_path[:-3], snapshot_name, 'html')
try:
@ -413,7 +413,10 @@ def check_snapshot(snapshot_name, tree):
else:
raise FailedCheck('No saved snapshot value')
actual_str = ET.tostring(tree).decode('utf-8')
if not normalize_to_text:
actual_str = ET.tostring(tree).decode('utf-8')
else:
actual_str = flatten(tree)
if expected_str != actual_str:
if bless:
@ -494,11 +497,16 @@ def check_command(c, cache):
[snapshot_name, html_path, pattern] = c.args
tree = cache.get_tree(html_path)
xpath = normalize_xpath(pattern)
normalize_to_text = False
if xpath.endswith('/text()'):
xpath = xpath[:-7]
normalize_to_text = True
subtrees = tree.findall(xpath)
if len(subtrees) == 1:
[subtree] = subtrees
try:
check_snapshot(snapshot_name, subtree)
check_snapshot(snapshot_name, subtree, normalize_to_text)
ret = True
except FailedCheck as err:
cerr = str(err)

View file

@ -492,9 +492,9 @@ impl<'tcx> Visitor<'tcx> for EmitIgnoredResolutionErrors<'tcx> {
"could not resolve path `{}`",
path.segments
.iter()
.map(|segment| segment.ident.as_str().to_string())
.collect::<Vec<_>>()
.join("::")
.map(|segment| segment.ident.as_str())
.intersperse("::")
.collect::<String>()
);
let mut err = rustc_errors::struct_span_err!(
self.tcx.sess,

View file

@ -422,6 +422,12 @@ fn settings(root_path: &str, suffix: &str, theme_names: Vec<String>) -> Result<S
"Theme preferences",
vec![
Setting::from(("use-system-theme", "Use system theme", true)),
Setting::Select {
js_data_name: "theme",
description: "Theme",
default_value: "light",
options: theme_names.clone(),
},
Setting::Select {
js_data_name: "preferred-dark-theme",
description: "Preferred dark theme",

View file

@ -944,11 +944,6 @@ h2.small-section-header > .anchor {
width: 100%;
}
#crate-search + .search-input {
border-radius: 0 1px 1px 0;
width: calc(100% - 32px);
}
.search-input:focus {
border-radius: 2px;
border: 0;
@ -1766,6 +1761,12 @@ details.rustdoc-toggle[open] > summary.hideme::after {
padding-top: 0px;
}
/* Space is at a premium on mobile, so remove the theme-picker icon. */
#theme-picker {
display: none;
width: 0;
}
.rustdoc {
flex-direction: column;
}
@ -1884,12 +1885,6 @@ details.rustdoc-toggle[open] > summary.hideme::after {
height: 100%;
}
nav.sub {
width: calc(100% - 32px);
margin-left: 32px;
margin-bottom: 10px;
}
.source nav:not(.sidebar).sub {
margin-left: 32px;
}
@ -2081,16 +2076,10 @@ details.rustdoc-toggle[open] > summary.hideme::after {
}
#crate-search {
width: 100%;
border-radius: 4px;
border: 0;
}
#crate-search + .search-input {
width: calc(100% + 71px);
margin-left: -36px;
}
#theme-picker, #settings-menu {
padding: 5px;
width: 31px;

View file

@ -299,7 +299,8 @@ details.undocumented > summary::before {
border-color: #5c6773;
}
.since {
.rightside,
.out-of-band {
color: grey;
}

View file

@ -256,7 +256,8 @@ details.undocumented > summary::before {
background: rgba(0,0,0,0);
}
.since {
.rightside,
.out-of-band {
color: grey;
}

View file

@ -243,6 +243,11 @@ details.undocumented > summary::before {
border-color: #bfbfbf;
}
.rightside,
.out-of-band {
color: grey;
}
.result-name .primitive > i, .result-name .keyword > i {
color: black;
}

View file

@ -129,10 +129,15 @@ function hideThemeButtonState() {
// Set up the theme picker list.
(function () {
if (!document.location.href.startsWith("file:///")) {
return;
}
var themeChoices = getThemesElement();
var themePicker = getThemePickerElement();
var availableThemes = getVar("themes").split(",");
removeClass(themeChoices.parentElement, "hidden");
function switchThemeButtonState() {
if (themeChoices.style.display === "block") {
hideThemeButtonState();
@ -283,9 +288,6 @@ function hideThemeButtonState() {
loadSearch();
}
// `crates{version}.js` should always be loaded before this script, so we can use it
// safely.
searchState.addCrateDropdown(window.ALL_CRATES);
var params = searchState.getQueryStringParams();
if (params.search !== undefined) {
var search = searchState.outputElement();
@ -295,30 +297,6 @@ function hideThemeButtonState() {
loadSearch();
}
},
addCrateDropdown: function(crates) {
var elem = document.getElementById("crate-search");
if (!elem) {
return;
}
var savedCrate = getSettingValue("saved-filter-crate");
for (var i = 0, len = crates.length; i < len; ++i) {
var option = document.createElement("option");
option.value = crates[i];
option.innerText = crates[i];
elem.appendChild(option);
// Set the crate filter from saved storage, if the current page has the saved crate
// filter.
//
// If not, ignore the crate filter -- we want to support filtering for crates on
// sites like doc.rust-lang.org where the crates may differ from page to page while
// on the
// same domain.
if (crates[i] === savedCrate) {
elem.value = savedCrate;
}
}
},
};
function getPageId() {
@ -897,6 +875,9 @@ function hideThemeButtonState() {
handleClick("help-button", function(ev) {
displayHelp(true, ev);
});
handleClick(MAIN_ID, function() {
hideSidebar();
});
onEachLazy(document.getElementsByTagName("a"), function(el) {
// For clicks on internal links (<A> tags with a hash property), we expand the section we're
@ -905,6 +886,7 @@ function hideThemeButtonState() {
if (el.hash) {
el.addEventListener("click", function() {
expandSection(el.hash.slice(1));
hideSidebar();
});
}
});

View file

@ -1126,15 +1126,18 @@ window.initSearch = function(rawSearchIndex) {
}
}
let crates = `<select id="crate-search"><option value="All crates">All crates</option>`;
for (let c of window.ALL_CRATES) {
crates += `<option value="${c}" ${c == filterCrates && "selected"}>${c}</option>`;
let crates = "";
if (window.ALL_CRATES.length > 1) {
crates = ` in <select id="crate-search"><option value="All crates">All crates</option>`;
for (let c of window.ALL_CRATES) {
crates += `<option value="${c}" ${c == filterCrates && "selected"}>${c}</option>`;
}
crates += `</select>`;
}
crates += `</select>`;
var output = `<div id="search-settings">
<h1 class="search-results-title">Results for ${escape(query.query)} ` +
(query.type ? " (type: " + escape(query.type) + ")" : "") + "</h1>" +
` in ${crates} ` +
crates +
`</div><div id="titles">` +
makeTabHeader(0, "In Names", ret_others[1]) +
makeTabHeader(1, "In Parameters", ret_in_args[1]) +
@ -1148,7 +1151,10 @@ window.initSearch = function(rawSearchIndex) {
resultsElem.appendChild(ret_returned[0]);
search.innerHTML = output;
document.getElementById("crate-search").addEventListener("input", updateCrate);
let crateSearch = document.getElementById("crate-search");
if (crateSearch) {
crateSearch.addEventListener("input", updateCrate);
}
search.appendChild(resultsElem);
// Reset focused elements.
searchState.focusedByTab = [null, null, null];

View file

@ -1,15 +1,18 @@
// Local js definitions:
/* global getSettingValue, getVirtualKey, onEachLazy, updateLocalStorage, updateSystemTheme */
/* global addClass, removeClass */
(function () {
function changeSetting(settingName, value) {
updateLocalStorage("rustdoc-" + settingName, value);
switch (settingName) {
case "theme":
case "preferred-dark-theme":
case "preferred-light-theme":
case "use-system-theme":
updateSystemTheme();
updateLightAndDark();
break;
}
}
@ -29,7 +32,32 @@
}
}
function showLightAndDark() {
addClass(document.getElementById("theme").parentElement.parentElement, "hidden");
removeClass(document.getElementById("preferred-light-theme").parentElement.parentElement,
"hidden");
removeClass(document.getElementById("preferred-dark-theme").parentElement.parentElement,
"hidden");
}
function hideLightAndDark() {
addClass(document.getElementById("preferred-light-theme").parentElement.parentElement,
"hidden");
addClass(document.getElementById("preferred-dark-theme").parentElement.parentElement,
"hidden");
removeClass(document.getElementById("theme").parentElement.parentElement, "hidden");
}
function updateLightAndDark() {
if (getSettingValue("use-system-theme") !== "false") {
showLightAndDark();
} else {
hideLightAndDark();
}
}
function setEvents() {
updateLightAndDark();
onEachLazy(document.getElementsByClassName("slider"), function(elem) {
var toggle = elem.previousElementSibling;
var settingId = toggle.id;

View file

@ -187,22 +187,25 @@ var updateSystemTheme = (function() {
var mql = window.matchMedia("(prefers-color-scheme: dark)");
function handlePreferenceChange(mql) {
let use = function(theme) {
switchTheme(window.currentTheme, window.mainTheme, theme, true);
};
// maybe the user has disabled the setting in the meantime!
if (getSettingValue("use-system-theme") !== "false") {
var lightTheme = getSettingValue("preferred-light-theme") || "light";
var darkTheme = getSettingValue("preferred-dark-theme") || "dark";
if (mql.matches) {
// prefers a dark theme
switchTheme(window.currentTheme, window.mainTheme, darkTheme, true);
use(darkTheme);
} else {
// prefers a light theme, or has no preference
switchTheme(window.currentTheme, window.mainTheme, lightTheme, true);
use(lightTheme);
}
// note: we save the theme so that it doesn't suddenly change when
// the user disables "use-system-theme" and reloads the page or
// navigates to another page
} else {
use(getSettingValue("theme"));
}
}

View file

@ -96,7 +96,7 @@
{%- endif -%}
</a> {#- -#}
<nav class="sub"> {#- -#}
<div class="theme-picker"> {#- -#}
<div class="theme-picker hidden"> {#- -#}
<button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu" title="themes"> {#- -#}
<img width="18" height="18" alt="Pick another theme!" {# -#}
src="{{static_root_path|safe}}brush{{page.resource_suffix}}.svg"> {#- -#}

View file

@ -19,7 +19,7 @@ thread_local!(static A: Cell<u32> = const { Cell::new(1) });
// CHECK-LABEL: @get
#[no_mangle]
fn get() -> u32 {
// CHECK: %0 = load i32, i32* bitcast ({{.*}} [[TLS]] to i32*)
// CHECK: %0 = load i32, i32* {{.*}}[[TLS]]{{.*}}
// CHECK-NEXT: ret i32 %0
A.with(|a| a.get())
}
@ -27,7 +27,7 @@ fn get() -> u32 {
// CHECK-LABEL: @set
#[no_mangle]
fn set(v: u32) {
// CHECK: store i32 %0, i32* bitcast ({{.*}} [[TLS]] to i32*)
// CHECK: store i32 %0, i32* {{.*}}[[TLS]]{{.*}}
// CHECK-NEXT: ret void
A.with(|a| a.set(v))
}

View file

@ -154,3 +154,16 @@ assert-css: ("h2#top-doc-prose-title", {"font-size": "20.8px"})
assert-css: ("h2#top-doc-prose-title", {"border-bottom-width": "1px"})
assert-css: ("h3#top-doc-prose-sub-heading", {"font-size": "18.4px"})
assert-css: ("h3#top-doc-prose-sub-heading", {"border-bottom-width": "1px"})
goto: file://|DOC_PATH|/staged_api/struct.Foo.html
show-text: true
local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
assert-css: (".since", {"color": "rgb(128, 128, 128)"})
local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
reload:
assert-css: (".since", {"color": "rgb(128, 128, 128)"})
local-storage: {"rustdoc-theme": "ayu", "rustdoc-use-system-theme": "false"}
reload:
assert-css: (".since", {"color": "rgb(128, 128, 128)"})

View file

@ -18,3 +18,11 @@ assert-css: (".sidebar-elems", {"display": "block", "left": "0px"})
// When we tab out of the sidebar, close it.
focus: ".search-input"
assert-css: (".sidebar-elems", {"display": "block", "left": "-246px"})
// Open the sidebar menu.
click: ".sidebar-menu"
assert-css: (".sidebar-elems", {"left": "0px"})
// Click elsewhere.
click: "body"
assert-css: (".sidebar-elems", {"left": "-246px"})

View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "staged_api"
version = "0.1.0"

View file

@ -0,0 +1,11 @@
[package]
name = "staged_api"
version = "0.1.0"
edition = "2021"
[lib]
path = "lib.rs"
[features]
default = ["some_feature"]
some_feature = []

View file

@ -0,0 +1,10 @@
#![feature(staged_api)]
#![stable(feature = "some_feature", since = "1.3.5")]
#[stable(feature = "some_feature", since = "1.3.5")]
pub struct Foo {}
impl Foo {
#[stable(feature = "some_feature", since = "1.3.5")]
pub fn bar() {}
}

View file

@ -1,12 +1,12 @@
goto: file://|DOC_PATH|/test_docs/struct.Foo.html
size: (433, 600)
assert-attribute: (".top-doc", {"open": ""})
click: (4, 240) // This is the position of the top doc comment toggle
click: (4, 260) // This is the position of the top doc comment toggle
assert-attribute-false: (".top-doc", {"open": ""})
click: (4, 240)
click: (4, 260)
assert-attribute: (".top-doc", {"open": ""})
// To ensure that the toggle isn't over the text, we check that the toggle isn't clicked.
click: (3, 240)
click: (3, 260)
assert-attribute: (".top-doc", {"open": ""})
// Assert the position of the toggle on the top doc block.
@ -22,10 +22,10 @@ assert-position: (
// Now we do the same but with a little bigger width
size: (600, 600)
assert-attribute: (".top-doc", {"open": ""})
click: (4, 240) // New Y position since all search elements are back on one line.
click: (4, 260) // New Y position since all search elements are back on one line.
assert-attribute-false: (".top-doc", {"open": ""})
click: (4, 240)
click: (4, 260)
assert-attribute: (".top-doc", {"open": ""})
// To ensure that the toggle isn't over the text, we check that the toggle isn't clicked.
click: (3, 240)
click: (3, 260)
assert-attribute: (".top-doc", {"open": ""})

View file

@ -0,0 +1,17 @@
// check-pass
struct Test<T>([T; 1]);
impl<T> std::ops::Deref for Test<T> {
type Target = [T; 1];
fn deref(&self) -> &[T; 1] {
&self.0
}
}
fn main() {
let out = Test([(); 1]);
let blah = out.len();
println!("{}", blah);
}

View file

@ -0,0 +1,27 @@
// check-pass
struct Test<T, const N: usize>([T; N]);
impl<T: Copy + Default, const N: usize> Default for Test<T, N> {
fn default() -> Self {
Self([T::default(); N])
}
}
impl<T, const N: usize> std::ops::Deref for Test<T, N> {
type Target = [T; N];
fn deref(&self) -> &[T; N] {
&self.0
}
}
fn test() -> Test<u64, 16> {
let test = Test::default();
println!("{}", test.len());
test
}
fn main() {
test();
}

View file

@ -1,5 +1,5 @@
#![allow(unused)]
#![feature(const_fn_trait_bound, const_trait_impl, inline_const)]
#![feature(const_fn_trait_bound, const_trait_impl, inline_const, negative_impls)]
const fn f<T: ~const Drop>(x: T) {}
@ -9,9 +9,15 @@ impl Drop for UnconstDrop {
fn drop(&mut self) {}
}
struct NonDrop;
impl !Drop for NonDrop {}
fn main() {
const {
f(UnconstDrop);
//~^ ERROR the trait bound `UnconstDrop: Drop` is not satisfied
f(NonDrop);
//~^ ERROR the trait bound `NonDrop: Drop` is not satisfied
}
}

View file

@ -1,5 +1,5 @@
error[E0277]: the trait bound `UnconstDrop: Drop` is not satisfied
--> $DIR/const-block-const-bound.rs:14:11
--> $DIR/const-block-const-bound.rs:18:11
|
LL | f(UnconstDrop);
| - ^^^^^^^^^^^ the trait `Drop` is not implemented for `UnconstDrop`
@ -16,6 +16,20 @@ help: consider introducing a `where` bound, but there might be an alternative be
LL | fn main() where UnconstDrop: Drop {
| +++++++++++++++++++++++
error: aborting due to previous error
error[E0277]: the trait bound `NonDrop: Drop` is not satisfied
--> $DIR/const-block-const-bound.rs:20:11
|
LL | f(NonDrop);
| - ^^^^^^^ the trait `Drop` is not implemented for `NonDrop`
| |
| required by a bound introduced by this call
|
note: required by a bound in `f`
--> $DIR/const-block-const-bound.rs:4:15
|
LL | const fn f<T: ~const Drop>(x: T) {}
| ^^^^^^^^^^^ required by this bound in `f`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,6 +1,7 @@
//~ NOTE not a function
//~^ NOTE not a foreign function or static
//~^^ NOTE not a function or static
//~| NOTE not a foreign function or static
//~| NOTE not a function or static
//~| NOTE not an `extern` block
// This test enumerates as many compiler-builtin ungated attributes as
// possible (that is, all the mutually compatible ones), and checks
// that we get "expected" (*) warnings for each in the various weird
@ -59,9 +60,9 @@
#![proc_macro_derive()] //~ WARN `#[proc_macro_derive]` only has an effect
#![doc = "2400"]
#![cold] //~ WARN attribute should be applied to a function
//~^ WARN
// see issue-43106-gating-of-builtin-attrs-error.rs
#![link()]
//~^ WARN this was previously accepted
#![link()] //~ WARN attribute should be applied to an `extern` block
//~^ WARN this was previously accepted
#![link_name = "1900"]
//~^ WARN attribute should be applied to a foreign function
//~^^ WARN this was previously accepted by the compiler
@ -547,22 +548,38 @@ mod link_section {
}
// Note that this is a `check-pass` test, so it
// will never invoke the linker. These are here nonetheless to point
// out that we allow them at non-crate-level (though I do not know
// whether they have the same effect here as at crate-level).
// Note that this is a `check-pass` test, so it will never invoke the linker.
#[link()]
//~^ WARN attribute should be applied to an `extern` block
//~| WARN this was previously accepted
mod link {
//~^ NOTE not an `extern` block
mod inner { #![link()] }
//~^ WARN attribute should be applied to an `extern` block
//~| WARN this was previously accepted
//~| NOTE not an `extern` block
#[link()] fn f() { }
//~^ WARN attribute should be applied to an `extern` block
//~| WARN this was previously accepted
//~| NOTE not an `extern` block
#[link()] struct S;
//~^ WARN attribute should be applied to an `extern` block
//~| WARN this was previously accepted
//~| NOTE not an `extern` block
#[link()] type T = S;
//~^ WARN attribute should be applied to an `extern` block
//~| WARN this was previously accepted
//~| NOTE not an `extern` block
#[link()] impl S { }
//~^ WARN attribute should be applied to an `extern` block
//~| WARN this was previously accepted
//~| NOTE not an `extern` block
}
struct StructForDeprecated;
@ -594,16 +611,22 @@ mod must_use {
}
#[windows_subsystem = "windows"]
//~^ WARN crate-level attribute should be an inner attribute
mod windows_subsystem {
mod inner { #![windows_subsystem="windows"] }
//~^ WARN crate-level attribute should be in the root module
#[windows_subsystem = "windows"] fn f() { }
//~^ WARN crate-level attribute should be an inner attribute
#[windows_subsystem = "windows"] struct S;
//~^ WARN crate-level attribute should be an inner attribute
#[windows_subsystem = "windows"] type T = S;
//~^ WARN crate-level attribute should be an inner attribute
#[windows_subsystem = "windows"] impl S { }
//~^ WARN crate-level attribute should be an inner attribute
}
// BROKEN USES OF CRATE-LEVEL BUILT-IN ATTRIBUTES
@ -686,16 +709,22 @@ mod no_main_1 {
}
#[no_builtins]
//~^ WARN crate-level attribute should be an inner attribute
mod no_builtins {
mod inner { #![no_builtins] }
//~^ WARN crate-level attribute should be in the root module
#[no_builtins] fn f() { }
//~^ WARN crate-level attribute should be an inner attribute
#[no_builtins] struct S;
//~^ WARN crate-level attribute should be an inner attribute
#[no_builtins] type T = S;
//~^ WARN crate-level attribute should be an inner attribute
#[no_builtins] impl S { }
//~^ WARN crate-level attribute should be an inner attribute
}
#[recursion_limit="0200"]