Auto merge of #101716 - Dylan-DPC:rollup-ayvh6nd, r=Dylan-DPC

Rollup of 9 pull requests

Successful merges:

 - #100293 (Add inline-llvm option for disabling/enabling LLVM inlining)
 - #100767 (Remove manual <[u8]>::escape_ascii)
 - #101668 (Suggest pub instead of public for const type item)
 - #101671 (Fix naming format of IEEE 754 standard)
 - #101676 (Check that the types in return position `impl Trait` in traits are well-formed)
 - #101681 (Deny return-position `impl Trait` in traits for object safety)
 - #101693 (Update browser UI test 0 10)
 - #101701 (Rustdoc-Json: Add tests for trait impls.)
 - #101706 (rustdoc: remove no-op `#search`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-09-12 13:16:14 +00:00
commit 7f115e3cd2
41 changed files with 372 additions and 105 deletions

View File

@ -473,6 +473,7 @@ impl Token {
kw::Extern,
kw::Impl,
kw::Unsafe,
kw::Const,
kw::Static,
kw::Union,
kw::Macro,

View File

@ -163,12 +163,7 @@ impl LitKind {
}
LitKind::Str(symbol, ast::StrStyle::Raw(n)) => (token::StrRaw(n), symbol, None),
LitKind::ByteStr(ref bytes) => {
let string = bytes
.iter()
.cloned()
.flat_map(ascii::escape_default)
.map(Into::<char>::into)
.collect::<String>();
let string = bytes.escape_ascii().to_string();
(token::ByteStr, Symbol::intern(&string), None)
}
LitKind::Byte(byte) => {

View File

@ -35,6 +35,10 @@ pub fn apply_to_callsite(callsite: &Value, idx: AttributePlace, attrs: &[&Attrib
/// Get LLVM attribute for the provided inline heuristic.
#[inline]
fn inline_attr<'ll>(cx: &CodegenCx<'ll, '_>, inline: InlineAttr) -> Option<&'ll Attribute> {
if !cx.tcx.sess.opts.unstable_opts.inline_llvm {
// disable LLVM inlining
return Some(AttributeKind::NoInline.create_attr(cx.llcx));
}
match inline {
InlineAttr::Hint => Some(AttributeKind::InlineHint.create_attr(cx.llcx)),
InlineAttr::Always => Some(AttributeKind::AlwaysInline.create_attr(cx.llcx)),

View File

@ -44,7 +44,7 @@ use std::io::{BufWriter, Write};
use std::ops::Deref;
use std::path::{Path, PathBuf};
use std::process::{ExitStatus, Output, Stdio};
use std::{ascii, char, env, fmt, fs, io, mem, str};
use std::{env, fmt, fs, io, mem, str};
pub fn ensure_removed(diag_handler: &Handler, path: &Path) {
if let Err(e) = fs::remove_file(path) {
@ -552,14 +552,6 @@ fn link_staticlib<'a>(
Ok(())
}
fn escape_stdout_stderr_string(s: &[u8]) -> String {
str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| {
let mut x = "Non-UTF-8 output: ".to_string();
x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from));
x
})
}
/// Use `thorin` (rust implementation of a dwarf packaging utility) to link DWARF objects into a
/// DWARF package.
fn link_dwarf_object<'a>(
@ -866,7 +858,7 @@ fn link_natively<'a>(
if !prog.status.success() {
let mut output = prog.stderr.clone();
output.extend_from_slice(&prog.stdout);
let escaped_output = escape_stdout_stderr_string(&output);
let escaped_output = escape_string(&output);
let mut err = sess.struct_err(&format!(
"linking with `{}` failed: {}",
linker_path.display(),
@ -934,8 +926,8 @@ fn link_natively<'a>(
sess.abort_if_errors();
}
info!("linker stderr:\n{}", escape_stdout_stderr_string(&prog.stderr));
info!("linker stdout:\n{}", escape_stdout_stderr_string(&prog.stdout));
info!("linker stderr:\n{}", escape_string(&prog.stderr));
info!("linker stdout:\n{}", escape_string(&prog.stdout));
}
Err(e) => {
let linker_not_found = e.kind() == io::ErrorKind::NotFound;
@ -1065,11 +1057,10 @@ fn strip_symbols_in_osx<'a>(sess: &'a Session, out_filename: &Path, option: Opti
}
fn escape_string(s: &[u8]) -> String {
str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| {
let mut x = "Non-UTF-8 output: ".to_string();
x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from));
x
})
match str::from_utf8(s) {
Ok(s) => s.to_owned(),
Err(_) => format!("Non-UTF-8 output: {}", s.escape_ascii()),
}
}
fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut dyn Linker) {

View File

@ -2633,15 +2633,7 @@ fn pretty_print_const<'tcx>(
}
fn pretty_print_byte_str(fmt: &mut Formatter<'_>, byte_str: &[u8]) -> fmt::Result {
fmt.write_str("b\"")?;
for &c in byte_str {
for e in std::ascii::escape_default(c) {
fmt.write_char(e as char)?;
}
}
fmt.write_str("\"")?;
Ok(())
write!(fmt, "b\"{}\"", byte_str.escape_ascii())
}
fn comma_sep<'tcx>(fmt: &mut Formatter<'_>, elems: Vec<ConstantKind<'tcx>>) -> fmt::Result {

View File

@ -915,6 +915,12 @@ impl ObjectSafetyViolation {
ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelfOutput, _) => {
format!("method `{}` references the `Self` type in its return type", name).into()
}
ObjectSafetyViolation::Method(
name,
MethodViolationCode::ReferencesImplTraitInTrait,
_,
) => format!("method `{}` references an `impl Trait` type in its return type", name)
.into(),
ObjectSafetyViolation::Method(
name,
MethodViolationCode::WhereClauseReferencesSelf,
@ -1021,6 +1027,9 @@ pub enum MethodViolationCode {
/// e.g., `fn foo(&self) -> Self`
ReferencesSelfOutput,
/// e.g., `fn foo(&self) -> impl Sized`
ReferencesImplTraitInTrait,
/// e.g., `fn foo(&self) where Self: Clone`
WhereClauseReferencesSelf,

View File

@ -1405,14 +1405,7 @@ pub trait PrettyPrinter<'tcx>:
}
fn pretty_print_byte_str(mut self, byte_str: &'tcx [u8]) -> Result<Self::Const, Self::Error> {
define_scoped_cx!(self);
p!("b\"");
for &c in byte_str {
for e in std::ascii::escape_default(c) {
self.write_char(e as char)?;
}
}
p!("\"");
write!(self, "b\"{}\"", byte_str.escape_ascii())?;
Ok(self)
}

View File

@ -1345,6 +1345,8 @@ options! {
"hash spans relative to their parent item for incr. comp. (default: no)"),
incremental_verify_ich: bool = (false, parse_bool, [UNTRACKED],
"verify incr. comp. hashes of green query instances (default: no)"),
inline_llvm: bool = (true, parse_bool, [TRACKED],
"enable LLVM inlining (default: yes)"),
inline_mir: Option<bool> = (None, parse_opt_bool, [TRACKED],
"enable MIR inlining (default: no)"),
inline_mir_threshold: Option<usize> = (None, parse_opt_number, [TRACKED],

View File

@ -13,6 +13,7 @@ use super::elaborate_predicates;
use crate::infer::TyCtxtInferExt;
use crate::traits::query::evaluate_obligation::InferCtxtExt;
use crate::traits::{self, Obligation, ObligationCause};
use hir::def::DefKind;
use rustc_errors::{FatalError, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
@ -431,6 +432,9 @@ fn virtual_call_violation_for_method<'tcx>(
if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output()) {
return Some(MethodViolationCode::ReferencesSelfOutput);
}
if contains_illegal_impl_trait_in_trait(tcx, sig.output()) {
return Some(MethodViolationCode::ReferencesImplTraitInTrait);
}
// We can't monomorphize things like `fn foo<A>(...)`.
let own_counts = tcx.generics_of(method.def_id).own_counts();
@ -793,6 +797,12 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(
ControlFlow::CONTINUE
}
}
ty::Projection(ref data)
if self.tcx.def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder =>
{
// We'll deny these later in their own pass
ControlFlow::CONTINUE
}
ty::Projection(ref data) => {
// This is a projected type `<Foo as SomeTrait>::X`.
@ -861,6 +871,22 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(
.is_break()
}
pub fn contains_illegal_impl_trait_in_trait<'tcx>(
tcx: TyCtxt<'tcx>,
ty: ty::Binder<'tcx, Ty<'tcx>>,
) -> bool {
// FIXME(RPITIT): Perhaps we should use a visitor here?
ty.skip_binder().walk().any(|arg| {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Projection(proj) = ty.kind()
{
tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
} else {
false
}
})
}
pub fn provide(providers: &mut ty::query::Providers) {
*providers = ty::query::Providers { object_safety_violations, ..*providers };
}

View File

@ -1,4 +1,5 @@
use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
use hir::def::DefKind;
use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
@ -1530,6 +1531,49 @@ fn check_fn_or_method<'tcx>(
);
check_where_clauses(wfcx, span, def_id);
check_return_position_impl_trait_in_trait_bounds(
tcx,
wfcx,
def_id,
sig.output(),
hir_decl.output.span(),
);
}
/// Basically `check_associated_type_bounds`, but separated for now and should be
/// deduplicated when RPITITs get lowered into real associated items.
fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
wfcx: &WfCheckingCtxt<'_, 'tcx>,
fn_def_id: LocalDefId,
fn_output: Ty<'tcx>,
span: Span,
) {
if let Some(assoc_item) = tcx.opt_associated_item(fn_def_id.to_def_id())
&& assoc_item.container == ty::AssocItemContainer::TraitContainer
{
for arg in fn_output.walk() {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Projection(proj) = ty.kind()
&& tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
&& tcx.impl_trait_in_trait_parent(proj.item_def_id) == fn_def_id.to_def_id()
{
let bounds = wfcx.tcx().explicit_item_bounds(proj.item_def_id);
let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| {
let normalized_bound = wfcx.normalize(span, None, bound);
traits::wf::predicate_obligations(
wfcx.infcx,
wfcx.param_env,
wfcx.body_id,
normalized_bound,
bound_span,
)
});
wfcx.register_obligations(wf_obligations);
}
}
}
}
const HELP_FOR_SELF_TYPE: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \

View File

@ -1,6 +1,6 @@
Equivalent to C's `double` type.
This type will almost always be [`f64`], which is guaranteed to be an [IEEE-754 double-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number with at least the precision of a [`float`], and it may be `f32` or something entirely different from the IEEE-754 standard.
This type will almost always be [`f64`], which is guaranteed to be an [IEEE 754 double-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number with at least the precision of a [`float`], and it may be `f32` or something entirely different from the IEEE-754 standard.
[IEEE-754 double-precision float]: https://en.wikipedia.org/wiki/IEEE_754
[IEEE 754 double-precision float]: https://en.wikipedia.org/wiki/IEEE_754
[`float`]: c_float

View File

@ -1,5 +1,5 @@
Equivalent to C's `float` type.
This type will almost always be [`f32`], which is guaranteed to be an [IEEE-754 single-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number, and it may have less precision than `f32` or not follow the IEEE-754 standard at all.
This type will almost always be [`f32`], which is guaranteed to be an [IEEE 754 single-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number, and it may have less precision than `f32` or not follow the IEEE-754 standard at all.
[IEEE-754 single-precision float]: https://en.wikipedia.org/wiki/IEEE_754
[IEEE 754 single-precision float]: https://en.wikipedia.org/wiki/IEEE_754

View File

@ -1,7 +1,6 @@
use crate::ascii;
use crate::cmp::Ordering;
use crate::ffi::c_char;
use crate::fmt::{self, Write};
use crate::fmt;
use crate::intrinsics;
use crate::ops;
use crate::slice;
@ -161,11 +160,7 @@ impl fmt::Display for FromBytesUntilNulError {
#[stable(feature = "cstr_debug", since = "1.3.0")]
impl fmt::Debug for CStr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "\"")?;
for byte in self.to_bytes().iter().flat_map(|&b| ascii::escape_default(b)) {
f.write_char(byte as char)?;
}
write!(f, "\"")
write!(f, "\"{}\"", self.to_bytes().escape_ascii())
}
}

View File

@ -32,7 +32,7 @@ impl Default for Decimal {
impl Decimal {
/// The maximum number of digits required to unambiguously round a float.
///
/// For a double-precision IEEE-754 float, this required 767 digits,
/// For a double-precision IEEE 754 float, this required 767 digits,
/// so we store the max digits + 1.
///
/// We can exactly represent a float in radix `b` from radix 2 if

View File

@ -394,7 +394,7 @@ impl f32 {
/// Not a Number (NaN).
///
/// Note that IEEE-754 doesn't define just a single NaN value;
/// Note that IEEE 754 doesn't define just a single NaN value;
/// a plethora of bit patterns are considered to be NaN.
/// Furthermore, the standard makes a difference
/// between a "signaling" and a "quiet" NaN,
@ -632,7 +632,7 @@ impl f32 {
}
/// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with
/// positive sign bit and positive infinity. Note that IEEE-754 doesn't assign any
/// positive sign bit and positive infinity. Note that IEEE 754 doesn't assign any
/// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
/// the bit pattern of NaNs are conserved over arithmetic operations, the result of
/// `is_sign_positive` on a NaN might produce an unexpected result in some cases.
@ -654,7 +654,7 @@ impl f32 {
}
/// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with
/// negative sign bit and negative infinity. Note that IEEE-754 doesn't assign any
/// negative sign bit and negative infinity. Note that IEEE 754 doesn't assign any
/// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
/// the bit pattern of NaNs are conserved over arithmetic operations, the result of
/// `is_sign_negative` on a NaN might produce an unexpected result in some cases.
@ -833,7 +833,7 @@ impl f32 {
/// Returns the maximum of the two numbers, ignoring NaN.
///
/// If one of the arguments is NaN, then the other argument is returned.
/// This follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs;
/// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
/// This also matches the behavior of libms fmax.
///
@ -853,7 +853,7 @@ impl f32 {
/// Returns the minimum of the two numbers, ignoring NaN.
///
/// If one of the arguments is NaN, then the other argument is returned.
/// This follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs;
/// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids minNum's problems with associativity.
/// This also matches the behavior of libms fmin.
///
@ -1051,9 +1051,9 @@ impl f32 {
/// It turns out this is incredibly portable, for two reasons:
///
/// * Floats and Ints have the same endianness on all supported platforms.
/// * IEEE-754 very precisely specifies the bit layout of floats.
/// * IEEE 754 very precisely specifies the bit layout of floats.
///
/// However there is one caveat: prior to the 2008 version of IEEE-754, how
/// However there is one caveat: prior to the 2008 version of IEEE 754, how
/// to interpret the NaN signaling bit wasn't actually specified. Most platforms
/// (notably x86 and ARM) picked the interpretation that was ultimately
/// standardized in 2008, but some didn't (notably MIPS). As a result, all

View File

@ -393,7 +393,7 @@ impl f64 {
/// Not a Number (NaN).
///
/// Note that IEEE-754 doesn't define just a single NaN value;
/// Note that IEEE 754 doesn't define just a single NaN value;
/// a plethora of bit patterns are considered to be NaN.
/// Furthermore, the standard makes a difference
/// between a "signaling" and a "quiet" NaN,
@ -624,7 +624,7 @@ impl f64 {
}
/// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with
/// positive sign bit and positive infinity. Note that IEEE-754 doesn't assign any
/// positive sign bit and positive infinity. Note that IEEE 754 doesn't assign any
/// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
/// the bit pattern of NaNs are conserved over arithmetic operations, the result of
/// `is_sign_positive` on a NaN might produce an unexpected result in some cases.
@ -655,7 +655,7 @@ impl f64 {
}
/// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with
/// negative sign bit and negative infinity. Note that IEEE-754 doesn't assign any
/// negative sign bit and negative infinity. Note that IEEE 754 doesn't assign any
/// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
/// the bit pattern of NaNs are conserved over arithmetic operations, the result of
/// `is_sign_negative` on a NaN might produce an unexpected result in some cases.
@ -844,7 +844,7 @@ impl f64 {
/// Returns the maximum of the two numbers, ignoring NaN.
///
/// If one of the arguments is NaN, then the other argument is returned.
/// This follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs;
/// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
/// This also matches the behavior of libms fmax.
///
@ -864,7 +864,7 @@ impl f64 {
/// Returns the minimum of the two numbers, ignoring NaN.
///
/// If one of the arguments is NaN, then the other argument is returned.
/// This follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs;
/// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids minNum's problems with associativity.
/// This also matches the behavior of libms fmin.
///
@ -1044,9 +1044,9 @@ impl f64 {
/// It turns out this is incredibly portable, for two reasons:
///
/// * Floats and Ints have the same endianness on all supported platforms.
/// * IEEE-754 very precisely specifies the bit layout of floats.
/// * IEEE 754 very precisely specifies the bit layout of floats.
///
/// However there is one caveat: prior to the 2008 version of IEEE-754, how
/// However there is one caveat: prior to the 2008 version of IEEE 754, how
/// to interpret the NaN signaling bit wasn't actually specified. Most platforms
/// (notably x86 and ARM) picked the interpretation that was ultimately
/// standardized in 2008, but some didn't (notably MIPS). As a result, all

View File

@ -1353,12 +1353,7 @@ impl Literal {
/// Byte string literal.
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub fn byte_string(bytes: &[u8]) -> Literal {
let string = bytes
.iter()
.cloned()
.flat_map(std::ascii::escape_default)
.map(Into::<char>::into)
.collect::<String>();
let string = bytes.escape_ascii().to_string();
Literal::new(bridge::LitKind::ByteStr, &string, None)
}

View File

@ -2,7 +2,7 @@ use crate::ffi::OsStr;
use crate::os::unix::ffi::OsStrExt;
use crate::path::Path;
use crate::sys::cvt;
use crate::{ascii, fmt, io, mem, ptr};
use crate::{fmt, io, mem, ptr};
// FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here?
#[cfg(not(unix))]
@ -64,18 +64,6 @@ enum AddressKind<'a> {
Abstract(&'a [u8]),
}
struct AsciiEscaped<'a>(&'a [u8]);
impl<'a> fmt::Display for AsciiEscaped<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "\"")?;
for byte in self.0.iter().cloned().flat_map(ascii::escape_default) {
write!(fmt, "{}", byte as char)?;
}
write!(fmt, "\"")
}
}
/// An address associated with a Unix socket.
///
/// # Examples
@ -343,7 +331,7 @@ impl fmt::Debug for SocketAddr {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.address() {
AddressKind::Unnamed => write!(fmt, "(unnamed)"),
AddressKind::Abstract(name) => write!(fmt, "{} (abstract)", AsciiEscaped(name)),
AddressKind::Abstract(name) => write!(fmt, "\"{}\" (abstract)", name.escape_ascii()),
AddressKind::Pathname(path) => write!(fmt, "{path:?} (pathname)"),
}
}

View File

@ -14,7 +14,7 @@ pub trait Stats {
/// Sum of the samples.
///
/// Note: this method sacrifices performance at the altar of accuracy
/// Depends on IEEE-754 arithmetic guarantees. See proof of correctness at:
/// Depends on IEEE 754 arithmetic guarantees. See proof of correctness at:
/// ["Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric
/// Predicates"][paper]
///

View File

@ -1891,11 +1891,6 @@ in storage.js plus the media query with (min-width: 701px)
margin-top: 10px;
}
#search {
margin-left: 0;
padding: 0;
}
.anchor {
display: none !important;
}

View File

@ -6,7 +6,7 @@ size: (1100, 800)
compare-elements-property: (".top-doc .docblock", ".top-doc .docblock > p", ["scrollWidth"])
assert-property: (".top-doc .docblock", {"scrollWidth": "801"})
// However, since there is overflow in the <table>, its scroll width is bigger.
assert-property: (".top-doc .docblock table", {"scrollWidth": "1573"})
assert-property: (".top-doc .docblock table", {"scrollWidth": "1572"})
// Checking it works on other doc blocks as well...
@ -18,4 +18,4 @@ compare-elements-property: (
)
assert-property: ("#implementations-list > details .docblock", {"scrollWidth": "801"})
// However, since there is overflow in the <table>, its scroll width is bigger.
assert-property: ("#implementations-list > details .docblock table", {"scrollWidth": "1573"})
assert-property: ("#implementations-list > details .docblock table", {"scrollWidth": "1572"})

View File

@ -6,7 +6,7 @@ assert-css: (".sidebar", {"display": "block", "left": "-1000px"})
// Scroll down.
scroll-to: "//h2[@id='blanket-implementations']"
assert-window-property: {"pageYOffset": "702"}
assert-window-property: {"pageYOffset": "643"}
// Open the sidebar menu.
click: ".sidebar-menu-toggle"
@ -21,11 +21,11 @@ assert-window-property: {"pageYOffset": "0"}
// Close the sidebar menu. Make sure the scroll position gets restored.
click: ".sidebar-menu-toggle"
wait-for-css: (".sidebar", {"left": "-1000px"})
assert-window-property: {"pageYOffset": "702"}
assert-window-property: {"pageYOffset": "643"}
// Now test that scrollability returns when the browser window is just resized.
click: ".sidebar-menu-toggle"
wait-for-css: (".sidebar", {"left": "0px"})
assert-window-property: {"pageYOffset": "0"}
size: (900, 900)
assert-window-property: {"pageYOffset": "702"}
size: (900, 600)
assert-window-property: {"pageYOffset": "643"}

View File

@ -224,14 +224,14 @@ click: "#sidebar-toggle"
wait-for-css: (".sidebar", {"width": "0px"})
// We scroll to line 117 to change the scroll position.
scroll-to: '//*[@id="117"]'
assert-window-property: {"pageYOffset": "2519"}
assert-window-property: {"pageYOffset": "2542"}
// Expanding the sidebar...
click: "#sidebar-toggle"
wait-for-css: (".sidebar", {"width": "500px"})
click: "#sidebar-toggle"
wait-for-css: (".sidebar", {"width": "0px"})
// The "scrollTop" property should be the same.
assert-window-property: {"pageYOffset": "2519"}
assert-window-property: {"pageYOffset": "2542"}
// We now check that the scroll position is restored if the window is resized.
size: (500, 700)
@ -239,7 +239,7 @@ click: "#sidebar-toggle"
wait-for-css: ("#source-sidebar", {"visibility": "visible"})
assert-window-property: {"pageYOffset": "0"}
size: (900, 900)
assert-window-property: {"pageYOffset": "2519"}
assert-window-property: {"pageYOffset": "2542"}
size: (500, 700)
click: "#sidebar-toggle"
wait-for-css: ("#source-sidebar", {"visibility": "hidden"})

View File

@ -4,7 +4,10 @@ goto: file://|DOC_PATH|/lib2/struct.Foo.html
assert-attribute: (".impl-items .rustdoc-toggle", {"open": ""})
click: "h4.code-header" // This is the position of "pub" in "pub fn a_method"
assert-attribute: (".impl-items .rustdoc-toggle", {"open": ""})
click: ".impl-items .rustdoc-toggle summary::before" // This is the position of "[-]" next to that pub fn.
click-with-offset: (
".impl-items .rustdoc-toggle summary",
{"x": -24, "y": 8}, // This is the position of "[-]" next to that pub fn.
)
assert-attribute-false: (".impl-items .rustdoc-toggle", {"open": ""})
// Click the "Trait" part of "impl Trait" and verify it navigates.

View File

@ -32,6 +32,6 @@ assert-property: (".item-decl pre", {"scrollWidth": "950"})
size: (600, 600)
goto: file://|DOC_PATH|/lib2/too_long/struct.SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName.html
// It shouldn't have an overflow in the topbar either.
assert-property: (".mobile-topbar .location", {"scrollWidth": "502"})
assert-property: (".mobile-topbar .location", {"clientWidth": "502"})
assert-property: (".mobile-topbar .location", {"scrollWidth": "500"})
assert-property: (".mobile-topbar .location", {"clientWidth": "500"})
assert-css: (".mobile-topbar .location", {"overflow-x": "hidden"})

View File

@ -0,0 +1 @@
pub struct ForeignStruct;

View File

@ -0,0 +1 @@
pub trait ForeignTrait {}

View File

@ -0,0 +1,18 @@
// aux-build: foreign_trait.rs
extern crate foreign_trait;
/// ForeignTrait id hack
pub use foreign_trait::ForeignTrait as _;
// @set ForeignTrait = "$.index[*][?(@.docs=='ForeignTrait id hack')].inner.id"
pub struct LocalStruct;
// @set LocalStruct = "$.index[*][?(@.name=='LocalStruct')].id"
/// foreign for local
impl foreign_trait::ForeignTrait for LocalStruct {}
// @set impl = "$.index[*][?(@.docs=='foreign for local')].id"
// @is "$.index[*][?(@.docs=='foreign for local')].inner.for.inner.id" $LocalStruct
// @is "$.index[*][?(@.docs=='foreign for local')].inner.trait.id" $ForeignTrait
// @has "$.index[*][?(@.name=='LocalStruct')].inner.impls[*]" $impl

View File

@ -0,0 +1,18 @@
// aux-build: foreign_struct.rs
extern crate foreign_struct;
/// ForeignStruct id hack
pub use foreign_struct::ForeignStruct as _;
// @set ForeignStruct = "$.index[*][?(@.docs=='ForeignStruct id hack')].inner.id"
pub trait LocalTrait {}
// @set LocalTrait = "$.index[*][?(@.name=='LocalTrait')].id"
/// local for foreign
impl LocalTrait for foreign_struct::ForeignStruct {}
// @set impl = "$.index[*][?(@.docs=='local for foreign')].id"
// @is "$.index[*][?(@.docs=='local for foreign')].inner.trait.id" $LocalTrait
// @is "$.index[*][?(@.docs=='local for foreign')].inner.for.inner.id" $ForeignStruct
// @is "$.index[*][?(@.name=='LocalTrait')].inner.implementations[*]" $impl

View File

@ -0,0 +1,15 @@
#![feature(no_core)]
#![no_core]
// @set struct = "$.index[*][?(@.name=='Struct')].id"
pub struct Struct;
// @set trait = "$.index[*][?(@.name=='Trait')].id"
pub trait Trait {}
// @set impl = "$.index[*][?(@.docs=='impl')].id"
/// impl
impl Trait for Struct {}
// @is "$.index[*][?(@.name=='Struct')].inner.impls[*]" $impl
// @is "$.index[*][?(@.name=='Trait')].inner.implementations[*]" $impl
// @is "$.index[*][?(@.docs=='impl')].inner.trait.id" $trait
// @is "$.index[*][?(@.docs=='impl')].inner.for.inner.id" $struct

View File

@ -0,0 +1,21 @@
#![feature(no_core)]
#![feature(rustdoc_internals)]
#![no_core]
// @set Local = "$.index[*][?(@.name=='Local')].id"
pub trait Local {}
// @is "$.index[*][?(@.docs=='Local for bool')].inner.trait.id" $Local
// @is "$.index[*][?(@.docs=='Local for bool')].inner.for.kind" '"primitive"'
// @is "$.index[*][?(@.docs=='Local for bool')].inner.for.inner" '"bool"'
/// Local for bool
impl Local for bool {}
// @set impl = "$.index[*][?(@.docs=='Local for bool')].id"
// @is "$.index[*][?(@.name=='Local')].inner.implementations[*]" $impl
// FIXME(#101695): Test bool's `impls` include "Local for bool"
// @has "$.index[*][?(@.name=='bool')]"
#[doc(primitive = "bool")]
/// Boolean docs
mod prim_bool {}

View File

@ -0,0 +1,7 @@
// @set local = "$.index[*][?(@.name=='Local')]"
pub trait Local {}
// @set impl = "$.index[*][?(@.docs=='local for bool')].id"
// @is "$.index[*][?(@.name=='Local')].inner.implementations[*]" $impl
/// local for bool
impl Local for bool {}

View File

@ -54,6 +54,7 @@
-Z incremental-info=val -- print high-level information about incremental reuse (or the lack thereof) (default: no)
-Z incremental-relative-spans=val -- hash spans relative to their parent item for incr. comp. (default: no)
-Z incremental-verify-ich=val -- verify incr. comp. hashes of green query instances (default: no)
-Z inline-llvm=val -- enable LLVM inlining (default: yes)
-Z inline-mir=val -- enable MIR inlining (default: no)
-Z inline-mir-threshold=val -- a default MIR inlining threshold (default: 50)
-Z inline-mir-hint-threshold=val -- inlining threshold for functions with inline hint (default: 100)

View File

@ -0,0 +1,22 @@
#![feature(return_position_impl_trait_in_trait)]
#![allow(incomplete_features)]
use std::fmt::Debug;
trait Foo {
fn baz(&self) -> impl Debug;
}
impl Foo for u32 {
fn baz(&self) -> u32 {
32
}
}
fn main() {
let i = Box::new(42_u32) as Box<dyn Foo>;
//~^ ERROR the trait `Foo` cannot be made into an object
//~| ERROR the trait `Foo` cannot be made into an object
let s = i.baz();
//~^ ERROR the trait `Foo` cannot be made into an object
}

View File

@ -0,0 +1,50 @@
error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/object-safety.rs:17:33
|
LL | let i = Box::new(42_u32) as Box<dyn Foo>;
| ^^^^^^^^^^^^ `Foo` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety.rs:7:8
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | fn baz(&self) -> impl Debug;
| ^^^ ...because method `baz` references an `impl Trait` type in its return type
= help: consider moving `baz` to another trait
error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/object-safety.rs:20:13
|
LL | let s = i.baz();
| ^^^^^^^ `Foo` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety.rs:7:8
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | fn baz(&self) -> impl Debug;
| ^^^ ...because method `baz` references an `impl Trait` type in its return type
= help: consider moving `baz` to another trait
error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/object-safety.rs:17:13
|
LL | let i = Box::new(42_u32) as Box<dyn Foo>;
| ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety.rs:7:8
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | fn baz(&self) -> impl Debug;
| ^^^ ...because method `baz` references an `impl Trait` type in its return type
= help: consider moving `baz` to another trait
= note: required for `Box<u32>` to implement `CoerceUnsized<Box<dyn Foo>>`
= note: required by cast to type `Box<dyn Foo>`
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0038`.

View File

@ -0,0 +1,16 @@
// issue #101663
#![feature(return_position_impl_trait_in_trait)]
#![allow(incomplete_features)]
trait Wf<T> {}
trait Uwu {
fn nya() -> impl Wf<Vec<[u8]>>;
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
fn nya2() -> impl Wf<[u8]>;
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
}
fn main() {}

View File

@ -0,0 +1,33 @@
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/wf-bounds.rs:9:22
|
LL | fn nya() -> impl Wf<Vec<[u8]>>;
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
note: required by a bound in `Vec`
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
| ^ required by this bound in `Vec`
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/wf-bounds.rs:12:23
|
LL | fn nya2() -> impl Wf<[u8]>;
| ^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
note: required by a bound in `Wf`
--> $DIR/wf-bounds.rs:6:10
|
LL | trait Wf<T> {}
| ^ required by this bound in `Wf`
help: consider relaxing the implicit `Sized` restriction
|
LL | trait Wf<T: ?Sized> {}
| ++++++++
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -0,0 +1,9 @@
// run-rustfix
mod test {
pub const X: i32 = 123;
//~^ ERROR expected one of `!` or `::`, found keyword `const`
}
fn main() {
println!("{}", test::X);
}

View File

@ -0,0 +1,9 @@
// run-rustfix
mod test {
public const X: i32 = 123;
//~^ ERROR expected one of `!` or `::`, found keyword `const`
}
fn main() {
println!("{}", test::X);
}

View File

@ -0,0 +1,13 @@
error: expected one of `!` or `::`, found keyword `const`
--> $DIR/public-instead-of-pub-3.rs:3:12
|
LL | public const X: i32 = 123;
| ^^^^^ expected one of `!` or `::`
|
help: write `pub` instead of `public` to make the item public
|
LL | pub const X: i32 = 123;
| ~~~
error: aborting due to previous error