Auto merge of #104083 - JohnTitor:rollup-lo3wbzs, r=JohnTitor

Rollup of 9 pull requests

Successful merges:

 - #103885 (rustdoc: various cross-crate reexport fixes)
 - #103914 (Make underscore_literal_suffix a hard error.)
 - #104045 (Add type_array to BaseTypeMethods)
 - #104056 (Vec: IntoIterator signature consistency)
 - #104059 (Fix typo in `rustc_middle/lint.rs`)
 - #104062 (rustdoc: remove unused CSS `#sidebar-filler`)
 - #104065 (Migrate rust logo filter to CSS variables)
 - #104066 (LLVM 16: Update RISCV data layout)
 - #104074 (rustdoc: Add an example for round that is different from truncate)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-11-07 02:15:39 +00:00
commit 9b735a7132
37 changed files with 242 additions and 144 deletions

View file

@ -201,6 +201,27 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn val_ty(&self, value: RValue<'gcc>) -> Type<'gcc> {
value.get_type()
}
fn type_array(&self, ty: Type<'gcc>, mut len: u64) -> Type<'gcc> {
if let Some(struct_type) = ty.is_struct() {
if struct_type.get_field_count() == 0 {
// NOTE: since gccjit only supports i32 for the array size and libcore's tests uses a
// size of usize::MAX in test_binary_search, we workaround this by setting the size to
// zero for ZSTs.
// FIXME(antoyo): fix gccjit API.
len = 0;
}
}
// NOTE: see note above. Some other test uses usize::MAX.
if len == u64::MAX {
len = 0;
}
let len: i32 = len.try_into().expect("array len");
self.context.new_array_type(None, ty, len)
}
}
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
@ -227,27 +248,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
self.context.new_opaque_struct_type(None, name)
}
pub fn type_array(&self, ty: Type<'gcc>, mut len: u64) -> Type<'gcc> {
if let Some(struct_type) = ty.is_struct() {
if struct_type.get_field_count() == 0 {
// NOTE: since gccjit only supports i32 for the array size and libcore's tests uses a
// size of usize::MAX in test_binary_search, we workaround this by setting the size to
// zero for ZSTs.
// FIXME(antoyo): fix gccjit API.
len = 0;
}
}
// NOTE: see note above. Some other test uses usize::MAX.
if len == u64::MAX {
len = 0;
}
let len: i32 = len.try_into().expect("array len");
self.context.new_array_type(None, ty, len)
}
pub fn type_bool(&self) -> Type<'gcc> {
self.context.new_type::<bool>()
}

View file

@ -158,6 +158,10 @@ pub unsafe fn create_module<'ll>(
if sess.target.arch == "s390x" {
target_data_layout = target_data_layout.replace("-v128:64", "");
}
if sess.target.arch == "riscv64" {
target_data_layout = target_data_layout.replace("-n32:64-", "-n64-");
}
}
// Ensure the data-layout values hardcoded remain the defaults.

View file

@ -127,10 +127,6 @@ impl<'ll> CodegenCx<'ll, '_> {
pub(crate) fn type_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, True) }
}
pub(crate) fn type_array(&self, ty: &'ll Type, len: u64) -> &'ll Type {
unsafe { llvm::LLVMRustArrayType(ty, len) }
}
}
impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
@ -231,6 +227,10 @@ impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn val_ty(&self, v: &'ll Value) -> &'ll Type {
common::val_ty(v)
}
fn type_array(&self, ty: &'ll Type, len: u64) -> &'ll Type {
unsafe { llvm::LLVMRustArrayType(ty, len) }
}
}
impl Type {

View file

@ -22,6 +22,7 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
fn type_f32(&self) -> Self::Type;
fn type_f64(&self) -> Self::Type;
fn type_array(&self, ty: Self::Type, len: u64) -> Self::Type;
fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type;
fn type_struct(&self, els: &[Self::Type], packed: bool) -> Self::Type;
fn type_kind(&self, ty: Self::Type) -> TypeKind;

View file

@ -88,7 +88,9 @@ pub enum TokenKind {
/// tokens.
UnknownPrefix,
/// Examples: `"12_u8"`, `"1.0e-40"`, `b"123`.
/// Examples: `12u8`, `1.0e-40`, `b"123"`. Note that `_` is an invalid
/// suffix, but may be present here on string and float literals. Users of
/// this type will need to check for and reject that case.
///
/// See [LiteralKind] for more details.
Literal { kind: LiteralKind, suffix_start: u32 },
@ -840,12 +842,13 @@ impl Cursor<'_> {
self.eat_decimal_digits()
}
// Eats the suffix of the literal, e.g. "_u8".
// Eats the suffix of the literal, e.g. "u8".
fn eat_literal_suffix(&mut self) {
self.eat_identifier();
}
// Eats the identifier.
// Eats the identifier. Note: succeeds on `_`, which isn't a valid
// identifer.
fn eat_identifier(&mut self) {
if !is_id_start(self.first()) {
return;

View file

@ -276,7 +276,7 @@ pub fn explain_lint_level_source(
/// The innermost function for emitting lints.
///
/// If you are loocking to implement a lint, look for higher level functions,
/// If you are looking to implement a lint, look for higher level functions,
/// for example:
/// - [`TyCtxt::emit_spanned_lint`]
/// - [`TyCtxt::struct_span_lint_hir`]

View file

@ -175,20 +175,10 @@ impl<'a> StringReader<'a> {
if string == "_" {
self.sess
.span_diagnostic
.struct_span_warn(
.struct_span_err(
self.mk_sp(suffix_start, self.pos),
"underscore literal suffix is not allowed",
)
.warn(
"this was previously accepted by the compiler but is \
being phased out; it will become a hard error in \
a future release!",
)
.note(
"see issue #42326 \
<https://github.com/rust-lang/rust/issues/42326> \
for more information",
)
.emit();
None
} else {

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
Target {
llvm_target: "riscv64-unknown-freebsd".into(),
pointer_width: 64,
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(),
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
arch: "riscv64".into(),
options: TargetOptions {
code_model: Some(CodeModel::Medium),

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
Target {
llvm_target: "riscv64-unknown-linux-gnu".into(),
pointer_width: 64,
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(),
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
arch: "riscv64".into(),
options: TargetOptions {
code_model: Some(CodeModel::Medium),

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
Target {
llvm_target: "riscv64-unknown-linux-musl".into(),
pointer_width: 64,
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(),
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
arch: "riscv64".into(),
options: TargetOptions {
code_model: Some(CodeModel::Medium),

View file

@ -3,7 +3,7 @@ use crate::spec::{RelocModel, Target, TargetOptions};
pub fn target() -> Target {
Target {
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(),
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
llvm_target: "riscv64".into(),
pointer_width: 64,
arch: "riscv64".into(),

View file

@ -4,7 +4,7 @@ pub fn target() -> Target {
Target {
llvm_target: "riscv64-unknown-openbsd".into(),
pointer_width: 64,
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(),
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
arch: "riscv64".into(),
options: TargetOptions {
code_model: Some(CodeModel::Medium),

View file

@ -3,7 +3,7 @@ use crate::spec::{RelocModel, Target, TargetOptions};
pub fn target() -> Target {
Target {
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(),
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
llvm_target: "riscv64".into(),
pointer_width: 64,
arch: "riscv64".into(),

View file

@ -2780,7 +2780,7 @@ impl<T, A: Allocator> IntoIterator for Vec<T, A> {
/// assert_eq!(v_iter.next(), None);
/// ```
#[inline]
fn into_iter(self) -> IntoIter<T, A> {
fn into_iter(self) -> Self::IntoIter {
unsafe {
let mut me = ManuallyDrop::new(self);
let alloc = ManuallyDrop::new(ptr::read(me.allocator()));
@ -2808,7 +2808,7 @@ impl<'a, T, A: Allocator> IntoIterator for &'a Vec<T, A> {
type Item = &'a T;
type IntoIter = slice::Iter<'a, T>;
fn into_iter(self) -> slice::Iter<'a, T> {
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
@ -2818,7 +2818,7 @@ impl<'a, T, A: Allocator> IntoIterator for &'a mut Vec<T, A> {
type Item = &'a mut T;
type IntoIter = slice::IterMut<'a, T>;
fn into_iter(self) -> slice::IterMut<'a, T> {
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}

View file

@ -77,9 +77,11 @@ impl f32 {
/// ```
/// let f = 3.3_f32;
/// let g = -3.3_f32;
/// let h = -3.7_f32;
///
/// assert_eq!(f.round(), 3.0);
/// assert_eq!(g.round(), -3.0);
/// assert_eq!(h.round(), -4.0);
/// ```
#[rustc_allow_incoherent_impl]
#[must_use = "method returns a new number and does not mutate the original value"]

View file

@ -77,9 +77,11 @@ impl f64 {
/// ```
/// let f = 3.3_f64;
/// let g = -3.3_f64;
/// let h = -3.7_f64;
///
/// assert_eq!(f.round(), 3.0);
/// assert_eq!(g.round(), -3.0);
/// assert_eq!(h.round(), -4.0);
/// ```
#[rustc_allow_incoherent_impl]
#[must_use = "method returns a new number and does not mutate the original value"]

View file

@ -336,10 +336,7 @@ where
match br {
// We only care about named late bound regions, as we need to add them
// to the 'for<>' section
ty::BrNamed(_, name) => Some(GenericParamDef {
name,
kind: GenericParamDefKind::Lifetime { outlives: vec![] },
}),
ty::BrNamed(_, name) => Some(GenericParamDef::lifetime(name)),
_ => None,
}
})

View file

@ -243,10 +243,19 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean
fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> Box<clean::Function> {
let sig = cx.tcx.fn_sig(did);
let predicates = cx.tcx.predicates_of(did);
let late_bound_regions = sig.bound_vars().into_iter().filter_map(|var| match var {
ty::BoundVariableKind::Region(ty::BrNamed(_, name)) if name != kw::UnderscoreLifetime => {
Some(clean::GenericParamDef::lifetime(name))
}
_ => None,
});
let predicates = cx.tcx.explicit_predicates_of(did);
let (generics, decl) = clean::enter_impl_trait(cx, |cx| {
// NOTE: generics need to be cleaned before the decl!
let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
let mut generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
// FIXME: This does not place parameters in source order (late-bound ones come last)
generics.params.extend(late_bound_regions);
let decl = clean_fn_decl_from_did_and_sig(cx, Some(did), sig);
(generics, decl)
});

View file

@ -12,7 +12,7 @@ pub(crate) mod utils;
use rustc_ast as ast;
use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
@ -182,10 +182,9 @@ fn clean_poly_trait_ref_with_bindings<'tcx>(
.collect_referenced_late_bound_regions(&poly_trait_ref)
.into_iter()
.filter_map(|br| match br {
ty::BrNamed(_, name) if name != kw::UnderscoreLifetime => Some(GenericParamDef {
name,
kind: GenericParamDefKind::Lifetime { outlives: vec![] },
}),
ty::BrNamed(_, name) if name != kw::UnderscoreLifetime => {
Some(GenericParamDef::lifetime(name))
}
_ => None,
})
.collect();
@ -741,10 +740,7 @@ fn clean_ty_generics<'tcx>(
p.get_bound_params()
.into_iter()
.flatten()
.map(|param| GenericParamDef {
name: param.0,
kind: GenericParamDefKind::Lifetime { outlives: Vec::new() },
})
.map(|param| GenericParamDef::lifetime(param.0))
.collect(),
));
}
@ -957,12 +953,14 @@ fn clean_args_from_types_and_names<'tcx>(
values: types
.iter()
.enumerate()
.map(|(i, ty)| {
let mut name = names.get(i).map_or(kw::Empty, |ident| ident.name);
if name.is_empty() {
name = kw::Underscore;
}
Argument { name, type_: clean_ty(ty, cx), is_const: false }
.map(|(i, ty)| Argument {
type_: clean_ty(ty, cx),
name: names
.get(i)
.map(|ident| ident.name)
.filter(|ident| !ident.is_empty())
.unwrap_or(kw::Underscore),
is_const: false,
})
.collect(),
}
@ -1024,7 +1022,11 @@ fn clean_fn_decl_from_did_and_sig<'tcx>(
.iter()
.map(|t| Argument {
type_: clean_middle_ty(*t, cx, None),
name: names.next().map_or(kw::Empty, |i| i.name),
name: names
.next()
.map(|i| i.name)
.filter(|i| !i.is_empty())
.unwrap_or(kw::Underscore),
is_const: false,
})
.collect(),
@ -1144,12 +1146,25 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
}
}
ty::AssocKind::Fn => {
let generics = clean_ty_generics(
let sig = tcx.fn_sig(assoc_item.def_id);
let late_bound_regions = sig.bound_vars().into_iter().filter_map(|var| match var {
ty::BoundVariableKind::Region(ty::BrNamed(_, name))
if name != kw::UnderscoreLifetime =>
{
Some(GenericParamDef::lifetime(name))
}
_ => None,
});
let mut generics = clean_ty_generics(
cx,
tcx.generics_of(assoc_item.def_id),
tcx.explicit_predicates_of(assoc_item.def_id),
);
let sig = tcx.fn_sig(assoc_item.def_id);
// FIXME: This does not place parameters in source order (late-bound ones come last)
generics.params.extend(late_bound_regions);
let mut decl = clean_fn_decl_from_did_and_sig(cx, Some(assoc_item.def_id), sig);
if assoc_item.fn_has_self_parameter {
@ -1281,7 +1296,16 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
..
}) = generics.params.iter_mut().find(|param| &param.name == arg)
{
param_bounds.extend(mem::take(bounds));
param_bounds.append(bounds);
} else if let WherePredicate::RegionPredicate { lifetime: Lifetime(arg), bounds } = &mut pred
&& let Some(GenericParamDef {
kind: GenericParamDefKind::Lifetime { outlives: param_bounds },
..
}) = generics.params.iter_mut().find(|param| &param.name == arg) {
param_bounds.extend(bounds.drain(..).map(|bound| match bound {
GenericBound::Outlives(lifetime) => lifetime,
_ => unreachable!(),
}));
} else {
where_predicates.push(pred);
}
@ -1653,6 +1677,9 @@ pub(crate) fn clean_middle_ty<'tcx>(
inline::record_extern_fqn(cx, did, ItemType::Trait);
// FIXME(fmease): Hide the trait-object lifetime bound if it coincides with its default
// to partially address #44306. Follow the rules outlined at
// https://doc.rust-lang.org/reference/lifetime-elision.html#default-trait-object-lifetimes
let lifetime = clean_middle_region(*reg);
let mut bounds = dids
.map(|did| {
@ -1680,8 +1707,22 @@ pub(crate) fn clean_middle_ty<'tcx>(
})
.collect();
let late_bound_regions: FxIndexSet<_> = obj
.iter()
.flat_map(|pb| pb.bound_vars())
.filter_map(|br| match br {
ty::BoundVariableKind::Region(ty::BrNamed(_, name))
if name != kw::UnderscoreLifetime =>
{
Some(GenericParamDef::lifetime(name))
}
_ => None,
})
.collect();
let late_bound_regions = late_bound_regions.into_iter().collect();
let path = external_path(cx, did, false, bindings, substs);
bounds.insert(0, PolyTrait { trait_: path, generic_params: Vec::new() });
bounds.insert(0, PolyTrait { trait_: path, generic_params: late_bound_regions });
DynTrait(bounds, lifetime)
}

View file

@ -51,10 +51,7 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> ThinVec<WP
let Some((bounds, _)) = tybounds.get_mut(ty) else { return true };
let bound_params = bound_params
.into_iter()
.map(|param| clean::GenericParamDef {
name: param.0,
kind: clean::GenericParamDefKind::Lifetime { outlives: Vec::new() },
})
.map(|param| clean::GenericParamDef::lifetime(param.0))
.collect();
merge_bounds(cx, bounds, bound_params, trait_did, name, rhs)
});
@ -99,9 +96,8 @@ pub(crate) fn merge_bounds(
let last = trait_ref.trait_.segments.last_mut().expect("segments were empty");
trait_ref.generic_params.append(&mut bound_params);
// Since the parameters (probably) originate from `tcx.collect_*_late_bound_regions` which
// returns a hash set, sort them alphabetically to guarantee a stable and deterministic
// output (and to fully deduplicate them).
// Sort parameters (likely) originating from a hashset alphabetically to
// produce predictable output (and to allow for full deduplication).
trait_ref.generic_params.sort_unstable_by(|p, q| p.name.as_str().cmp(q.name.as_str()));
trait_ref.generic_params.dedup_by_key(|p| p.name);

View file

@ -1437,6 +1437,10 @@ pub(crate) struct GenericParamDef {
}
impl GenericParamDef {
pub(crate) fn lifetime(name: Symbol) -> Self {
Self { name, kind: GenericParamDefKind::Lifetime { outlives: Vec::new() } }
}
pub(crate) fn is_synthetic_type_param(&self) -> bool {
match self.kind {
GenericParamDefKind::Lifetime { .. } | GenericParamDefKind::Const { .. } => false,

View file

@ -4,7 +4,7 @@ use crate::clean::render_macro_matchers::render_macro_matcher;
use crate::clean::{
clean_doc_module, clean_middle_const, clean_middle_region, clean_middle_ty, inline, Crate,
ExternalCrate, Generic, GenericArg, GenericArgs, ImportSource, Item, ItemKind, Lifetime, Path,
PathSegment, Primitive, PrimitiveType, Type, TypeBinding,
PathSegment, Primitive, PrimitiveType, Term, Type, TypeBinding, TypeBindingKind,
};
use crate::core::DocContext;
use crate::html::format::visibility_to_src_with_space;
@ -113,12 +113,12 @@ fn external_generic_args<'tcx>(
ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(t, cx, None)).collect::<Vec<_>>().into(),
_ => return GenericArgs::AngleBracketed { args: args.into(), bindings },
};
let output = None;
// FIXME(#20299) return type comes from a projection now
// match types[1].kind {
// ty::Tuple(ref v) if v.is_empty() => None, // -> ()
// _ => Some(types[1].clean(cx))
// };
let output = bindings.into_iter().next().and_then(|binding| match binding.kind {
TypeBindingKind::Equality { term: Term::Type(ty) } if ty != Type::Tuple(Vec::new()) => {
Some(Box::new(ty))
}
_ => None,
});
GenericArgs::Parenthesized { inputs, output }
} else {
GenericArgs::AngleBracketed { args: args.into(), bindings: bindings.into() }

View file

@ -1232,9 +1232,8 @@ impl clean::Arguments {
) -> impl fmt::Display + 'a + Captures<'tcx> {
display_fn(move |f| {
for (i, input) in self.values.iter().enumerate() {
if !input.name.is_empty() {
write!(f, "{}: ", input.name)?;
}
write!(f, "{}: ", input.name)?;
if f.alternate() {
write!(f, "{:#}", input.type_.print(cx))?;
} else {
@ -1367,10 +1366,8 @@ impl clean::FnDecl {
args.push_str("const ");
args_plain.push_str("const ");
}
if !input.name.is_empty() {
write!(args, "{}: ", input.name);
write!(args_plain, "{}: ", input.name);
}
write!(args, "{}: ", input.name);
write!(args_plain, "{}: ", input.name);
if f.alternate() {
write!(args, "{:#}", input.type_.print(cx));

View file

@ -378,6 +378,10 @@ img {
object-fit: contain;
}
.rust-logo {
filter: var(--rust-logo-filter);
}
.sidebar, .mobile-topbar, .sidebar-menu-toggle {
background-color: var(--sidebar-background-color);
}
@ -1804,21 +1808,6 @@ in storage.js
display: block;
}
/* Because of ios, we need to actually have a full height sidebar title so the
* actual sidebar can show up. But then we need to make it transparent so we don't
* hide content. The filler just allows to create the background for the sidebar
* title. But because of the absolute position, I had to lower the z-index.
*/
#sidebar-filler {
position: fixed;
left: 45px;
width: calc(100% - 45px);
top: 0;
height: 45px;
z-index: -1;
border-bottom: 1px solid;
}
#main-content > details.rustdoc-toggle > summary::before,
#main-content > div > details.rustdoc-toggle > summary::before {
left: -11px;

View file

@ -63,6 +63,10 @@ Original by Dempfi (https://github.com/dempfi/ayu)
--test-arrow-background-color: rgba(57, 175, 215, 0.09);
--test-arrow-hover-color: #c5c5c5;
--test-arrow-hover-background-color: rgba(57, 175, 215, 0.368);
--rust-logo-filter: drop-shadow(1px 0 0px #fff)
drop-shadow(0 1px 0 #fff)
drop-shadow(-1px 0 0 #fff)
drop-shadow(0 -1px 0 #fff);
}
.slider {
@ -104,13 +108,6 @@ pre, .rustdoc.source .example-wrap {
color: #e6e1cf;
}
.rust-logo {
filter: drop-shadow(1px 0 0px #fff)
drop-shadow(0 1px 0 #fff)
drop-shadow(-1px 0 0 #fff)
drop-shadow(0 -1px 0 #fff);
}
.sidebar .current,
.sidebar a:hover {
color: #ffb44c;

View file

@ -58,6 +58,10 @@
--test-arrow-background-color: rgba(78, 139, 202, 0.2);
--test-arrow-hover-color: #dedede;
--test-arrow-hover-background-color: #4e8bca;
--rust-logo-filter: drop-shadow(1px 0 0px #fff)
drop-shadow(0 1px 0 #fff)
drop-shadow(-1px 0 0 #fff)
drop-shadow(0 -1px 0 #fff);
}
.slider {
@ -70,13 +74,6 @@ input:focus + .slider {
box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3);
}
.rust-logo {
filter: drop-shadow(1px 0 0px #fff)
drop-shadow(0 1px 0 #fff)
drop-shadow(-1px 0 0 #fff)
drop-shadow(0 -1px 0 #fff)
}
.content .item-info::before { color: #ccc; }
body.source .example-wrap pre.rust a {

View file

@ -58,6 +58,7 @@
--test-arrow-background-color: rgba(78, 139, 202, 0.2);
--test-arrow-hover-color: #f5f5f5;
--test-arrow-hover-background-color: #4e8bca;
--rust-logo-filter: initial;
}
.slider {
@ -70,12 +71,6 @@ input:focus + .slider {
box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3);
}
.rust-logo {
/* This rule exists to force other themes to explicitly style the logo.
* Rustdoc has a custom linter for this purpose.
*/
}
.content .item-info::before { color: #ccc; }
body.source .example-wrap pre.rust a {

View file

@ -17,6 +17,15 @@ define-function: (
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
("reload"),
("assert-css", (".rust-logo", {"filter": |filter|})),
// Now we check that the non-rust logos don't have a CSS filter set.
("goto", "file://" + |DOC_PATH| + "/huge_logo/index.html"),
// Changing theme on the new page (again...).
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
("reload"),
// Check there is no rust logo
("assert-false", ".rust-logo"),
// Check there is no filter.
("assert-css", (".sidebar .logo-container img", {"filter": "none"})),
],
)

View file

@ -46,6 +46,7 @@ pub fn f(_: &(ToString + 'static)) {}
impl Bar {
// @has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.F"]' \
// "const F: fn(_: &(dyn ToString + 'static))"
// FIXME(fmease): Hide default lifetime, render "const F: fn(_: &dyn ToString)"
pub const F: fn(_: &(ToString + 'static)) = f;
}

View file

@ -33,8 +33,12 @@ extern crate assoc_item_trait_bounds as aux;
// @snapshot out9 - '//*[@id="associatedtype.Out9"]/*[@class="code-header"]'
//
// @has - '//*[@id="tymethod.make"]' \
// "fn make<F>(F, impl FnMut(&str) -> bool)\
// "fn make<F>(_: F, _: impl FnMut(&str) -> bool)\
// where \
// F: FnOnce(u32) -> String, \
// Self::Out2<()>: Protocol<u8, Q0 = Self::Item, Q1 = ()>"
pub use aux::Main;
// @has main/trait.Aid.html
// @has - '//*[@id="associatedtype.Result"]' "type Result<'inter: 'src>"
pub use aux::Aid;

View file

@ -42,5 +42,5 @@ pub trait Helper {
}
pub trait Aid<'src> {
type Result<'inter>;
type Result<'inter: 'src>;
}

View file

@ -0,0 +1,17 @@
pub type Ty0 = dyn for<'any> FnOnce(&'any str) -> bool;
pub type Ty1<'obj> = dyn std::fmt::Display + 'obj;
pub type Ty2 = dyn for<'a, 'r> Container<'r, Item<'a, 'static> = ()>;
pub type Ty3<'s> = &'s dyn ToString;
pub fn func0(_: &(dyn Fn() + '_)) {}
pub fn func1<'func>(_: &(dyn Fn() + 'func)) {}
pub trait Container<'r> {
type Item<'a, 'ctx>;
}
pub trait Shape<'a> {}

View file

@ -0,0 +1,31 @@
#![crate_name = "user"]
// aux-crate:dyn_trait=dyn_trait.rs
// edition:2021
// @has user/type.Ty0.html
// @has - '//*[@class="item-decl"]//code' "dyn for<'any> FnOnce(&'any str) -> bool + 'static"
// FIXME(fmease): Hide default lifetime bound `'static`
pub use dyn_trait::Ty0;
// @has user/type.Ty1.html
// @has - '//*[@class="item-decl"]//code' "dyn Display + 'obj"
pub use dyn_trait::Ty1;
// @has user/type.Ty2.html
// @has - '//*[@class="item-decl"]//code' "dyn for<'a, 'r> Container<'r, Item<'a, 'static> = ()>"
pub use dyn_trait::Ty2;
// @has user/type.Ty3.html
// @has - '//*[@class="item-decl"]//code' "&'s (dyn ToString + 's)"
// FIXME(fmease): Hide default lifetime bound, render "&'s dyn ToString"
pub use dyn_trait::Ty3;
// @has user/fn.func0.html
// @has - '//pre[@class="rust fn"]' "func0(_: &dyn Fn())"
// FIXME(fmease): Show placeholder-lifetime bound, render "func0(_: &(dyn Fn() + '_))"
pub use dyn_trait::func0;
// @has user/fn.func1.html
// @has - '//pre[@class="rust fn"]' "func1<'func>(_: &(dyn Fn() + 'func))"
pub use dyn_trait::func1;

View file

@ -29,7 +29,7 @@ pub use impl_trait_aux::func4;
// @has impl_trait/fn.func5.html
// @has - '//pre[@class="rust fn"]' "func5("
// @has - '//pre[@class="rust fn"]' "_f: impl for<'any> Fn(&'any str, &'any str) -> bool + for<'r> Other<T<'r> = ()>,"
// @has - '//pre[@class="rust fn"]' "_a: impl for<'alpha, 'beta> Auxiliary<'alpha, Item<'beta> = fn(&'beta ())>"
// @has - '//pre[@class="rust fn"]' "_a: impl for<'alpha, 'beta> Auxiliary<'alpha, Item<'beta> = fn(_: &'beta ())>"
// @!has - '//pre[@class="rust fn"]' 'where'
pub use impl_trait_aux::func5;

View file

@ -19,6 +19,6 @@ pub mod reexport {
// @has - '//*[@class="rust trait"]' 'trait Deref {'
// @has - '//*[@class="rust trait"]' 'type Target: ?Sized;'
// @has - '//*[@class="rust trait"]' \
// "fn deref(&'a self) -> &'a Self::Target;"
// "fn deref<'a>(&'a self) -> &'a Self::Target;"
pub use issue_20727::Deref;
}

View file

@ -1,8 +1,17 @@
// check-pass
macro_rules! sink {
($tt:tt) => {()}
}
fn main() {
let _ = "Foo"_;
//~^ WARNING underscore literal suffix is not allowed
//~| WARNING this was previously accepted
//~| NOTE issue #42326
//~^ ERROR underscore literal suffix is not allowed
// This is ok, because `__` is a valid identifier and the macro consumes it
// before proper parsing happens.
let _ = sink!("Foo"__);
// This is not ok, even as an input to a macro, because the `_` suffix is
// never allowed.
sink!("Foo"_);
//~^ ERROR underscore literal suffix is not allowed
}

View file

@ -1,11 +1,14 @@
warning: underscore literal suffix is not allowed
--> $DIR/underscore-suffix-for-string.rs:4:18
error: underscore literal suffix is not allowed
--> $DIR/underscore-suffix-for-string.rs:6:18
|
LL | let _ = "Foo"_;
| ^
error: underscore literal suffix is not allowed
--> $DIR/underscore-suffix-for-string.rs:15:16
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: see issue #42326 <https://github.com/rust-lang/rust/issues/42326> for more information
LL | sink!("Foo"_);
| ^
warning: 1 warning emitted
error: aborting due to 2 previous errors