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:
commit
7531d2fdd4
|
@ -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;
|
||||
}
|
||||
|
|
53
compiler/rustc_ast_pretty/src/pp/ring.rs
Normal file
53
compiler/rustc_ast_pretty/src/pp/ring.rs
Normal 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()]
|
||||
}
|
||||
}
|
|
@ -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!(
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
)
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 }
|
||||
})
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
|
|
|
@ -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
|
||||
})
|
||||
})
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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)?;
|
||||
///
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -299,7 +299,8 @@ details.undocumented > summary::before {
|
|||
border-color: #5c6773;
|
||||
}
|
||||
|
||||
.since {
|
||||
.rightside,
|
||||
.out-of-band {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
|
|
|
@ -256,7 +256,8 @@ details.undocumented > summary::before {
|
|||
background: rgba(0,0,0,0);
|
||||
}
|
||||
|
||||
.since {
|
||||
.rightside,
|
||||
.out-of-band {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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"> {#- -#}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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)"})
|
||||
|
|
|
@ -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"})
|
||||
|
|
7
src/test/rustdoc-gui/src/staged_api/Cargo.lock
Normal file
7
src/test/rustdoc-gui/src/staged_api/Cargo.lock
Normal 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"
|
11
src/test/rustdoc-gui/src/staged_api/Cargo.toml
Normal file
11
src/test/rustdoc-gui/src/staged_api/Cargo.toml
Normal 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 = []
|
10
src/test/rustdoc-gui/src/staged_api/lib.rs
Normal file
10
src/test/rustdoc-gui/src/staged_api/lib.rs
Normal 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() {}
|
||||
}
|
|
@ -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": ""})
|
||||
|
|
17
src/test/ui/autoref-autoderef/deref-into-array.rs
Normal file
17
src/test/ui/autoref-autoderef/deref-into-array.rs
Normal 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);
|
||||
}
|
27
src/test/ui/const-generics/deref-into-array-generic.rs
Normal file
27
src/test/ui/const-generics/deref-into-array-generic.rs
Normal 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();
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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"]
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue