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:
commit
8d36948b15
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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!(
|
||||
|
@ -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));
|
||||
let reported =
|
||||
tcx.sess.emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span });
|
||||
return tcx.ty_error();
|
||||
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)
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -36,6 +36,7 @@
|
||||
#![feature(let_chains)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(never_type)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -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,
|
||||
|
@ -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(())
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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| {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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!(
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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!(
|
||||
|
@ -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;
|
||||
|
@ -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`
|
||||
|
||||
|
80
src/test/ui/consts/fn_trait_refs.rs
Normal file
80
src/test/ui/consts/fn_trait_refs.rs
Normal 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);
|
||||
}
|
@ -12,6 +12,7 @@ allow-unauthenticated = [
|
||||
"T-*",
|
||||
"WG-*",
|
||||
"const-hack",
|
||||
"llvm-main",
|
||||
"needs-fcp",
|
||||
"relnotes",
|
||||
"requires-nightly",
|
||||
|
Loading…
Reference in New Issue
Block a user