Auto merge of #104168 - GuillaumeGomez:rollup-tf4edqc, r=GuillaumeGomez

Rollup of 12 pull requests

Successful merges:

 - #103928 (Add 'ty_error_with_guaranteed' and 'const_error_with_guaranteed')
 - #104027 (Place config.toml in current working directory if config not found)
 - #104093 (disable btree size tests on Miri)
 - #104097 (run alloc benchmarks in Miri and fix UB)
 - #104104 (Add split-debuginfo print option)
 - #104109 (rustdoc: Add mutable to the description)
 - #104113 (Fix `const_fn_trait_ref_impl`, add test for it)
 - #104114 (Fix invalid background-image file name)
 - #104132 (fix: lint against lint functions)
 - #104139 (Clarify licensing situation of MPSC and SPSC queue)
 - #104147 (Remove an address comparison from the parser)
 - #104165 (Add llvm-main to triagebot.toml)

Failed merges:

 - #104115 (Migrate crate-search element to CSS variables)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-11-08 22:50:12 +00:00
commit 8d36948b15
36 changed files with 235 additions and 93 deletions

View File

@ -299,8 +299,8 @@ fn infer_opaque_definition_from_instantiation(
if errors.is_empty() {
definition_ty
} else {
infcx.err_ctxt().report_fulfillment_errors(&errors, None);
self.tcx.ty_error()
let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None);
self.tcx.ty_error_with_guaranteed(reported)
}
}
}

View File

@ -247,12 +247,13 @@ pub(crate) fn create(mut self) -> CreateResult<'tcx> {
.and(type_op::normalize::Normalize::new(ty))
.fully_perform(self.infcx)
.unwrap_or_else(|_| {
self.infcx
let reported = self
.infcx
.tcx
.sess
.delay_span_bug(span, &format!("failed to normalize {:?}", ty));
TypeOpOutput {
output: self.infcx.tcx.ty_error(),
output: self.infcx.tcx.ty_error_with_guaranteed(reported),
constraints: None,
error_info: None,
}

View File

@ -233,11 +233,11 @@ pub(crate) fn type_check<'mir, 'tcx>(
let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind());
if hidden_type.has_non_region_infer() {
infcx.tcx.sess.delay_span_bug(
let reported = infcx.tcx.sess.delay_span_bug(
decl.hidden_type.span,
&format!("could not resolve {:#?}", hidden_type.ty.kind()),
);
hidden_type.ty = infcx.tcx.ty_error();
hidden_type.ty = infcx.tcx.ty_error_with_guaranteed(reported);
}
(opaque_type_key, (hidden_type, decl.origin))

View File

@ -736,6 +736,17 @@ fn print_crate_info(
// Any output here interferes with Cargo's parsing of other printed output
NativeStaticLibs => {}
LinkArgs => {}
SplitDebuginfo => {
use rustc_target::spec::SplitDebuginfo::{Off, Packed, Unpacked};
for split in &[Off, Packed, Unpacked] {
let stable = sess.target.options.supported_split_debuginfo.contains(split);
let unstable_ok = sess.unstable_options();
if stable || unstable_ok {
println!("{}", split);
}
}
}
}
}
Compilation::Stop

View File

@ -482,9 +482,9 @@ pub fn buffer(self, buffered_diagnostics: &mut Vec<Diagnostic>) {
/// In the meantime, though, callsites are required to deal with the "bug"
/// locally in whichever way makes the most sense.
#[track_caller]
pub fn delay_as_bug(&mut self) {
pub fn delay_as_bug(&mut self) -> G {
self.downgrade_to_delayed_bug();
self.emit();
self.emit()
}
forward!(

View File

@ -1201,7 +1201,8 @@ fn add_predicates_for_ast_type_binding(
(_, _) => {
let got = if let Some(_) = term.ty() { "type" } else { "constant" };
let expected = def_kind.descr(assoc_item_def_id);
tcx.sess
let reported = tcx
.sess
.struct_span_err(
binding.span,
&format!("expected {expected} bound, found {got}"),
@ -1212,11 +1213,14 @@ fn add_predicates_for_ast_type_binding(
)
.emit();
term = match def_kind {
hir::def::DefKind::AssocTy => tcx.ty_error().into(),
hir::def::DefKind::AssocTy => {
tcx.ty_error_with_guaranteed(reported).into()
}
hir::def::DefKind::AssocConst => tcx
.const_error(
.const_error_with_guaranteed(
tcx.bound_type_of(assoc_item_def_id)
.subst(tcx, projection_ty.skip_binder().substs),
reported,
)
.into(),
_ => unreachable!(),
@ -1334,8 +1338,9 @@ trait here instead: `trait NewTrait: {} {{}}`",
.map(|&(trait_ref, _, _)| trait_ref.def_id())
.find(|&trait_ref| tcx.is_trait_alias(trait_ref))
.map(|trait_ref| tcx.def_span(trait_ref));
tcx.sess.emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span });
return tcx.ty_error();
let reported =
tcx.sess.emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span });
return tcx.ty_error_with_guaranteed(reported);
}
// Check that there are no gross object safety violations;
@ -1345,14 +1350,14 @@ trait here instead: `trait NewTrait: {} {{}}`",
let object_safety_violations =
astconv_object_safety_violations(tcx, item.trait_ref().def_id());
if !object_safety_violations.is_empty() {
report_object_safety_error(
let reported = report_object_safety_error(
tcx,
span,
item.trait_ref().def_id(),
&object_safety_violations,
)
.emit();
return tcx.ty_error();
return tcx.ty_error_with_guaranteed(reported);
}
}
@ -2112,13 +2117,13 @@ fn qpath_to_ty(
"Type"
};
self.report_ambiguous_associated_type(
let reported = self.report_ambiguous_associated_type(
span,
type_name,
&path_str,
item_segment.ident.name,
);
return tcx.ty_error();
return tcx.ty_error_with_guaranteed(reported)
};
debug!("qpath_to_ty: self_type={:?}", self_ty);
@ -2560,8 +2565,7 @@ pub fn res_to_ty(
{
err.span_note(impl_.self_ty.span, "not a concrete type");
}
err.emit();
tcx.ty_error()
tcx.ty_error_with_guaranteed(err.emit())
} else {
self.normalize_ty(span, ty)
}

View File

@ -611,11 +611,11 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
collected_tys.insert(def_id, ty);
}
Err(err) => {
tcx.sess.delay_span_bug(
let reported = tcx.sess.delay_span_bug(
return_span,
format!("could not fully resolve: {ty} => {err:?}"),
);
collected_tys.insert(def_id, tcx.ty_error());
collected_tys.insert(def_id, tcx.ty_error_with_guaranteed(reported));
}
}
}

View File

@ -512,8 +512,7 @@ fn projected_ty_from_poly_trait_ref(
}
_ => {}
}
err.emit();
self.tcx().ty_error()
self.tcx().ty_error_with_guaranteed(err.emit())
}
}

View File

@ -698,7 +698,7 @@ fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) {
}
let Some(hidden) = locator.found else {
tcx.sess.emit_err(UnconstrainedOpaqueType {
let reported = tcx.sess.emit_err(UnconstrainedOpaqueType {
span: tcx.def_span(def_id),
name: tcx.item_name(tcx.local_parent(def_id).to_def_id()),
what: match tcx.hir().get(scope) {
@ -708,7 +708,7 @@ fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) {
_ => "item",
},
});
return tcx.ty_error();
return tcx.ty_error_with_guaranteed(reported);
};
// Only check against typeck if we didn't already error

View File

@ -1639,9 +1639,9 @@ pub(crate) fn coerce_inner<'a>(
if visitor.ret_exprs.len() > 0 && let Some(expr) = expression {
self.note_unreachable_loop_return(&mut err, &expr, &visitor.ret_exprs);
}
err.emit_unless(unsized_return);
let reported = err.emit_unless(unsized_return);
self.final_ty = Some(fcx.tcx.ty_error());
self.final_ty = Some(fcx.tcx.ty_error_with_guaranteed(reported));
}
}
}

View File

@ -80,14 +80,14 @@ fn check_expr_meets_expectation_or_error(
// coercions from ! to `expected`.
if ty.is_never() {
if let Some(adjustments) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
self.tcx().sess.delay_span_bug(
let reported = self.tcx().sess.delay_span_bug(
expr.span,
"expression with never type wound up being adjusted",
);
return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &adjustments[..] {
target.to_owned()
} else {
self.tcx().ty_error()
self.tcx().ty_error_with_guaranteed(reported)
};
}
@ -396,8 +396,7 @@ fn check_expr_unary(
{
err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
}
err.emit();
oprnd_t = tcx.ty_error();
oprnd_t = tcx.ty_error_with_guaranteed(err.emit());
}
}
hir::UnOp::Not => {
@ -1097,12 +1096,8 @@ fn check_expr_assign(
// If the assignment expression itself is ill-formed, don't
// bother emitting another error
if lhs_ty.references_error() || rhs_ty.references_error() {
err.delay_as_bug()
} else {
err.emit();
}
return self.tcx.ty_error();
let reported = err.emit_unless(lhs_ty.references_error() || rhs_ty.references_error());
return self.tcx.ty_error_with_guaranteed(reported);
}
let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
@ -2777,8 +2772,8 @@ fn check_expr_index(
);
}
}
err.emit();
self.tcx.ty_error()
let reported = err.emit();
self.tcx.ty_error_with_guaranteed(reported)
}
}
}

View File

@ -1212,9 +1212,8 @@ pub fn instantiate_value_path(
}
}
}
err.emit();
return (tcx.ty_error(), res);
let reported = err.emit();
return (tcx.ty_error_with_guaranteed(reported), res);
}
}
} else {

View File

@ -529,8 +529,8 @@ fn check_overloaded_binop(
}
}
}
err.emit();
self.tcx.ty_error()
let reported = err.emit();
self.tcx.ty_error_with_guaranteed(reported)
}
};

View File

@ -1278,12 +1278,12 @@ fn check_pat_tuple(
let element_tys = tcx.mk_type_list(element_tys_iter);
let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
if let Some(mut err) = self.demand_eqtype_pat_diag(span, expected, pat_ty, ti) {
err.emit();
let reported = err.emit();
// Walk subpatterns with an expected type of `err` in this case to silence
// further errors being emitted when using the bindings. #50333
let element_tys_iter = (0..max_len).map(|_| tcx.ty_error());
let element_tys_iter = (0..max_len).map(|_| tcx.ty_error_with_guaranteed(reported));
for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
self.check_pat(elem, tcx.ty_error(), def_bm, ti);
self.check_pat(elem, tcx.ty_error_with_guaranteed(reported), def_bm, ti);
}
tcx.mk_tup(element_tys_iter)
} else {

View File

@ -90,8 +90,11 @@ fn negative_index(
Applicability::MachineApplicable,
);
}
err.emit();
Some((self.tcx.ty_error(), self.tcx.ty_error()))
let reported = err.emit();
Some((
self.tcx.ty_error_with_guaranteed(reported),
self.tcx.ty_error_with_guaranteed(reported),
))
}
/// To type-check `base_expr[index_expr]`, we progressively autoderef

View File

@ -579,6 +579,7 @@ pub trait LintContext: Sized {
/// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
///
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
#[rustc_lint_diagnostics]
fn lookup_with_diagnostics(
&self,
lint: &'static Lint,
@ -882,6 +883,7 @@ fn lookup_with_diagnostics(
/// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
///
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
#[rustc_lint_diagnostics]
fn lookup<S: Into<MultiSpan>>(
&self,
lint: &'static Lint,
@ -908,6 +910,7 @@ fn emit_spanned_lint<S: Into<MultiSpan>>(
/// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
///
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
#[rustc_lint_diagnostics]
fn struct_span_lint<S: Into<MultiSpan>>(
&self,
lint: &'static Lint,
@ -933,6 +936,7 @@ fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> DecorateLint<'a
/// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
///
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
#[rustc_lint_diagnostics]
fn lint(
&self,
lint: &'static Lint,

View File

@ -1073,6 +1073,7 @@ pub fn lint_level(&self, lint: &'static Lint) -> LevelAndSource {
/// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
///
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
#[rustc_lint_diagnostics]
pub(crate) fn struct_lint(
&self,
lint: &'static Lint,

View File

@ -36,6 +36,7 @@
#![feature(let_chains)]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(rustc_attrs)]
#![recursion_limit = "256"]
#[macro_use]

View File

@ -1283,6 +1283,12 @@ pub fn create_global_ctxt(
}
}
/// Constructs a `TyKind::Error` type with current `ErrorGuaranteed`
#[track_caller]
pub fn ty_error_with_guaranteed(self, reported: ErrorGuaranteed) -> Ty<'tcx> {
self.mk_ty(Error(reported))
}
/// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
#[track_caller]
pub fn ty_error(self) -> Ty<'tcx> {
@ -1297,6 +1303,16 @@ pub fn ty_error_with_message<S: Into<MultiSpan>>(self, span: S, msg: &str) -> Ty
self.mk_ty(Error(reported))
}
/// Like [TyCtxt::ty_error] but for constants, with current `ErrorGuaranteed`
#[track_caller]
pub fn const_error_with_guaranteed(
self,
ty: Ty<'tcx>,
reported: ErrorGuaranteed,
) -> Const<'tcx> {
self.mk_const(ty::ConstKind::Error(reported), ty)
}
/// Like [TyCtxt::ty_error] but for constants.
#[track_caller]
pub fn const_error(self, ty: Ty<'tcx>) -> Const<'tcx> {
@ -2856,6 +2872,7 @@ pub fn emit_lint(
/// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
///
/// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
#[rustc_lint_diagnostics]
pub fn struct_lint_node(
self,
lint: &'static Lint,

View File

@ -97,7 +97,11 @@ fn references_error(&self) -> bool {
}
fn error_reported(&self) -> Result<(), ErrorGuaranteed> {
if self.references_error() {
Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
if let Some(reported) = ty::tls::with(|tcx| tcx.sess.has_errors()) {
Err(reported)
} else {
bug!("expect tcx.sess.has_errors return true");
}
} else {
Ok(())
}

View File

@ -833,16 +833,11 @@ fn parse_and_disallow_postfix_after_cast(
("cast", None)
};
// Save the memory location of expr before parsing any following postfix operators.
// This will be compared with the memory location of the output expression.
// If they different we can assume we parsed another expression because the existing expression is not reallocated.
let addr_before = &*cast_expr as *const _ as usize;
let with_postfix = self.parse_dot_or_call_expr_with_(cast_expr, span)?;
let changed = addr_before != &*with_postfix as *const _ as usize;
// Check if an illegal postfix operator has been added after the cast.
// If the resulting expression is not a cast, or has a different memory location, it is an illegal postfix operator.
if !matches!(with_postfix.kind, ExprKind::Cast(_, _) | ExprKind::Type(_, _)) || changed {
// If the resulting expression is not a cast, it is an illegal postfix operator.
if !matches!(with_postfix.kind, ExprKind::Cast(_, _) | ExprKind::Type(_, _)) {
let msg = format!(
"{cast_kind} cannot be followed by {}",
match with_postfix.kind {

View File

@ -548,6 +548,7 @@ pub enum PrintRequest {
NativeStaticLibs,
StackProtectorStrategies,
LinkArgs,
SplitDebuginfo,
}
pub enum Input {
@ -1806,6 +1807,7 @@ fn collect_print_requests(
("stack-protector-strategies", PrintRequest::StackProtectorStrategies),
("target-spec-json", PrintRequest::TargetSpec),
("link-args", PrintRequest::LinkArgs),
("split-debuginfo", PrintRequest::SplitDebuginfo),
];
prints.extend(matches.opt_strs("print").into_iter().map(|req| {

View File

@ -22,7 +22,6 @@ fn allocate_zeroed() {
}
#[bench]
#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
fn alloc_owned_small(b: &mut Bencher) {
b.iter(|| {
let _: Box<_> = Box::new(10);

View File

@ -94,6 +94,7 @@ fn test_partial_eq() {
#[test]
#[cfg(target_arch = "x86_64")]
#[cfg_attr(miri, ignore)] // We'd like to run Miri with layout randomization
fn test_sizes() {
assert_eq!(core::mem::size_of::<LeafNode<(), ()>>(), 16);
assert_eq!(core::mem::size_of::<LeafNode<i64, i64>>(), 16 + CAPACITY * 2 * 8);

View File

@ -3,7 +3,6 @@
use super::*;
#[bench]
#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
fn bench_push_back_100(b: &mut test::Bencher) {
let mut deq = VecDeque::with_capacity(101);
b.iter(|| {
@ -16,7 +15,6 @@ fn bench_push_back_100(b: &mut test::Bencher) {
}
#[bench]
#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
fn bench_push_front_100(b: &mut test::Bencher) {
let mut deq = VecDeque::with_capacity(101);
b.iter(|| {
@ -29,12 +27,15 @@ fn bench_push_front_100(b: &mut test::Bencher) {
}
#[bench]
#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
fn bench_pop_back_100(b: &mut test::Bencher) {
let mut deq = VecDeque::<i32>::with_capacity(101);
let size = 100;
let mut deq = VecDeque::<i32>::with_capacity(size + 1);
// We'll mess with private state to pretend like `deq` is filled.
// Make sure the buffer is initialized so that we don't read uninit memory.
unsafe { deq.ptr().write_bytes(0u8, size + 1) };
b.iter(|| {
deq.head = 100;
deq.head = size;
deq.tail = 0;
while !deq.is_empty() {
test::black_box(deq.pop_back());
@ -43,9 +44,9 @@ fn bench_pop_back_100(b: &mut test::Bencher) {
}
#[bench]
#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
fn bench_retain_whole_10000(b: &mut test::Bencher) {
let v = (1..100000).collect::<VecDeque<u32>>();
let size = if cfg!(miri) { 1000 } else { 100000 };
let v = (1..size).collect::<VecDeque<u32>>();
b.iter(|| {
let mut v = v.clone();
@ -54,9 +55,9 @@ fn bench_retain_whole_10000(b: &mut test::Bencher) {
}
#[bench]
#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
fn bench_retain_odd_10000(b: &mut test::Bencher) {
let v = (1..100000).collect::<VecDeque<u32>>();
let size = if cfg!(miri) { 1000 } else { 100000 };
let v = (1..size).collect::<VecDeque<u32>>();
b.iter(|| {
let mut v = v.clone();
@ -65,23 +66,26 @@ fn bench_retain_odd_10000(b: &mut test::Bencher) {
}
#[bench]
#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
fn bench_retain_half_10000(b: &mut test::Bencher) {
let v = (1..100000).collect::<VecDeque<u32>>();
let size = if cfg!(miri) { 1000 } else { 100000 };
let v = (1..size).collect::<VecDeque<u32>>();
b.iter(|| {
let mut v = v.clone();
v.retain(|x| *x > 50000)
v.retain(|x| *x > size / 2)
})
}
#[bench]
#[cfg_attr(miri, ignore)] // isolated Miri does not support benchmarks
fn bench_pop_front_100(b: &mut test::Bencher) {
let mut deq = VecDeque::<i32>::with_capacity(101);
let size = 100;
let mut deq = VecDeque::<i32>::with_capacity(size + 1);
// We'll mess with private state to pretend like `deq` is filled.
// Make sure the buffer is initialized so that we don't read uninit memory.
unsafe { deq.ptr().write_bytes(0u8, size + 1) };
b.iter(|| {
deq.head = 100;
deq.head = size;
deq.tail = 0;
while !deq.is_empty() {
test::black_box(deq.pop_front());

View File

@ -576,9 +576,10 @@ mod impls {
use crate::marker::Tuple;
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Tuple, F: ?Sized> Fn<A> for &F
#[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")]
impl<A: Tuple, F: ?Sized> const Fn<A> for &F
where
F: Fn<A>,
F: ~const Fn<A>,
{
extern "rust-call" fn call(&self, args: A) -> F::Output {
(**self).call(args)
@ -586,9 +587,10 @@ extern "rust-call" fn call(&self, args: A) -> F::Output {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Tuple, F: ?Sized> FnMut<A> for &F
#[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")]
impl<A: Tuple, F: ?Sized> const FnMut<A> for &F
where
F: Fn<A>,
F: ~const Fn<A>,
{
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
(**self).call(args)
@ -596,9 +598,10 @@ extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Tuple, F: ?Sized> FnOnce<A> for &F
#[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")]
impl<A: Tuple, F: ?Sized> const FnOnce<A> for &F
where
F: Fn<A>,
F: ~const Fn<A>,
{
type Output = F::Output;
@ -608,9 +611,10 @@ extern "rust-call" fn call_once(self, args: A) -> F::Output {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Tuple, F: ?Sized> FnMut<A> for &mut F
#[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")]
impl<A: Tuple, F: ?Sized> const FnMut<A> for &mut F
where
F: FnMut<A>,
F: ~const FnMut<A>,
{
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
(*self).call_mut(args)
@ -618,9 +622,10 @@ extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Tuple, F: ?Sized> FnOnce<A> for &mut F
#[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")]
impl<A: Tuple, F: ?Sized> const FnOnce<A> for &mut F
where
F: FnMut<A>,
F: ~const FnMut<A>,
{
type Output = F::Output;
extern "rust-call" fn call_once(self, args: A) -> F::Output {

View File

@ -3524,8 +3524,8 @@ pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T]) {
}
}
/// Transmute the slice to a slice of another type, ensuring alignment of the types is
/// maintained.
/// Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the
/// types is maintained.
///
/// This method splits the slice into three distinct slices: prefix, correctly aligned middle
/// slice of a new type, and the suffix slice. The method may make the middle slice the greatest

View File

@ -8,8 +8,15 @@
//! method, and see the method for more information about it. Due to this
//! caveat, this queue might not be appropriate for all use-cases.
// https://www.1024cores.net/home/lock-free-algorithms
// /queues/non-intrusive-mpsc-node-based-queue
// The original implementation is based off:
// https://www.1024cores.net/home/lock-free-algorithms/queues/non-intrusive-mpsc-node-based-queue
//
// Note that back when the code was imported, it was licensed under the BSD-2-Clause license:
// http://web.archive.org/web/20110411011612/https://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue
//
// The original author of the code agreed to relicense it under `MIT OR Apache-2.0` in 2017, so as
// of today the license of this file is the same as the rest of the codebase:
// https://github.com/rust-lang/rust/pull/42149
#[cfg(all(test, not(target_os = "emscripten")))]
mod tests;

View File

@ -4,7 +4,15 @@
//! concurrently between two threads. This data structure is safe to use and
//! enforces the semantics that there is one pusher and one popper.
// The original implementation is based off:
// https://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue
//
// Note that back when the code was imported, it was licensed under the BSD-2-Clause license:
// http://web.archive.org/web/20110411011612/https://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue
//
// The original author of the code agreed to relicense it under `MIT OR Apache-2.0` in 2017, so as
// of today the license of this file is the same as the rest of the codebase:
// https://github.com/rust-lang/rust/pull/42149
#[cfg(all(test, not(target_os = "emscripten")))]
mod tests;

View File

@ -35,7 +35,7 @@ fn main() {
// NOTE: Since `./configure` generates a `config.toml`, distro maintainers will see the
// changelog warning, not the `x.py setup` message.
let suggest_setup = !config.config.exists() && !matches!(config.cmd, Subcommand::Setup { .. });
let suggest_setup = config.config.is_none() && !matches!(config.cmd, Subcommand::Setup { .. });
if suggest_setup {
println!("warning: you have not made a `config.toml`");
println!(

View File

@ -80,7 +80,7 @@ pub struct Config {
pub keep_stage_std: Vec<u32>,
pub src: PathBuf,
/// defaults to `config.toml`
pub config: PathBuf,
pub config: Option<PathBuf>,
pub jobs: Option<u32>,
pub cmd: Subcommand,
pub incremental: bool,
@ -926,8 +926,10 @@ pub fn parse(args: &[String]) -> Config {
// Give a hard error if `--config` or `RUST_BOOTSTRAP_CONFIG` are set to a missing path,
// but not if `config.toml` hasn't been created.
let mut toml = if !using_default_path || toml_path.exists() {
config.config = Some(toml_path.clone());
get_toml(&toml_path)
} else {
config.config = None;
TomlConfig::default()
};
@ -942,7 +944,6 @@ pub fn parse(args: &[String]) -> Config {
}
config.changelog_seen = toml.changelog_seen;
config.config = toml_path;
let build = toml.build.unwrap_or_default();

View File

@ -82,7 +82,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
pub fn setup(config: &Config, profile: Profile) {
let path = &config.config;
let path = &config.config.clone().unwrap_or(PathBuf::from("config.toml"));
if path.exists() {
eprintln!(

View File

@ -854,7 +854,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
background-size: 20px;
background-position: calc(100% - 2px) 56%;
/* image is black color, themes should apply a "filter" property to change the color */
background-image: url("down-arrow-2d685a4bae708e15.svg");
background-image: url("down-arrow-927217e04c7463ac.svg");
}
#crate-search > option {
font-size: 1rem;

View File

@ -1,2 +1,2 @@
error: unknown print request `uwu`. Valid print requests are: `crate-name`, `file-names`, `sysroot`, `target-libdir`, `cfg`, `calling-conventions`, `target-list`, `target-cpus`, `target-features`, `relocation-models`, `code-models`, `tls-models`, `native-static-libs`, `stack-protector-strategies`, `target-spec-json`, `link-args`
error: unknown print request `uwu`. Valid print requests are: `crate-name`, `file-names`, `sysroot`, `target-libdir`, `cfg`, `calling-conventions`, `target-list`, `target-cpus`, `target-features`, `relocation-models`, `code-models`, `tls-models`, `native-static-libs`, `stack-protector-strategies`, `target-spec-json`, `link-args`, `split-debuginfo`

View File

@ -0,0 +1,80 @@
// build-pass
#![feature(const_fn_trait_ref_impls)]
#![feature(fn_traits)]
#![feature(unboxed_closures)]
#![feature(const_trait_impl)]
#![feature(const_mut_refs)]
#![feature(const_cmp)]
#![feature(const_refs_to_cell)]
use std::marker::Destruct;
const fn tester_fn<T>(f: T) -> T::Output
where
T: ~const Fn<()> + ~const Destruct,
{
f()
}
const fn tester_fn_mut<T>(mut f: T) -> T::Output
where
T: ~const FnMut<()> + ~const Destruct,
{
f()
}
const fn tester_fn_once<T>(f: T) -> T::Output
where
T: ~const FnOnce<()>,
{
f()
}
const fn test_fn<T>(mut f: T) -> (T::Output, T::Output, T::Output)
where
T: ~const Fn<()> + ~const Destruct,
{
(
// impl<A: Tuple, F: ~const Fn + ?Sized> const Fn<A> for &F
tester_fn(&f),
// impl<A: Tuple, F: ~const Fn + ?Sized> const FnMut<A> for &F
tester_fn_mut(&f),
// impl<A: Tuple, F: ~const Fn + ?Sized> const FnOnce<A> for &F
tester_fn_once(&f),
)
}
const fn test_fn_mut<T>(mut f: T) -> (T::Output, T::Output)
where
T: ~const FnMut<()> + ~const Destruct,
{
(
// impl<A: Tuple, F: ~const FnMut + ?Sized> const FnMut<A> for &mut F
tester_fn_mut(&mut f),
// impl<A: Tuple, F: ~const FnMut + ?Sized> const FnOnce<A> for &mut F
tester_fn_once(&mut f),
)
}
const fn test(i: i32) -> i32 {
i + 1
}
const fn main() {
const fn one() -> i32 {
1
};
const fn two() -> i32 {
2
};
// FIXME(const_cmp_tuple)
let test_one = test_fn(one);
assert!(test_one.0 == 1);
assert!(test_one.1 == 1);
assert!(test_one.2 == 1);
let test_two = test_fn_mut(two);
assert!(test_two.0 == 1);
assert!(test_two.1 == 1);
}

View File

@ -12,6 +12,7 @@ allow-unauthenticated = [
"T-*",
"WG-*",
"const-hack",
"llvm-main",
"needs-fcp",
"relnotes",
"requires-nightly",