Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0004b3b

Browse files
committedMay 25, 2023
Auto merge of #111960 - compiler-errors:rollup-onka2dl, r=compiler-errors
Rollup of 7 pull requests Successful merges: - #107522 (Add Median of Medians fallback to introselect) - #111152 (update `pulldown-cmark` to `0.9.3`) - #111757 (Consider lint check attributes on match arms) - #111831 (Always capture slice when pattern requires checking the length) - #111929 (Don't print newlines in APITs) - #111945 (Migrate GUI colors test to original CSS color format) - #111950 (Remove ExpnKind::Inlined.) r? `@ghost` `@rustbot` modify labels: rollup
2 parents a2b1646 + c2e3521 commit 0004b3b

File tree

37 files changed

+856
-411
lines changed

37 files changed

+856
-411
lines changed
 

‎Cargo.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2779,9 +2779,9 @@ dependencies = [
27792779

27802780
[[package]]
27812781
name = "pulldown-cmark"
2782-
version = "0.9.2"
2782+
version = "0.9.3"
27832783
source = "registry+https://github.com/rust-lang/crates.io-index"
2784-
checksum = "2d9cc634bc78768157b5cbfe988ffcd1dcba95cd2b2f03a88316c08c6d00ed63"
2784+
checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998"
27852785
dependencies = [
27862786
"bitflags",
27872787
"memchr",

‎compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1425,7 +1425,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
14251425
DefPathData::ImplTrait,
14261426
span,
14271427
);
1428-
let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
1428+
1429+
// HACK: pprust breaks strings with newlines when the type
1430+
// gets too long. We don't want these to show up in compiler
1431+
// output or built artifacts, so replace them here...
1432+
// Perhaps we should instead format APITs more robustly.
1433+
let ident = Ident::from_str_and_span(
1434+
&pprust::ty_to_string(t).replace('\n', " "),
1435+
span,
1436+
);
1437+
14291438
let (param, bounds, path) = self.lower_universal_param_and_bounds(
14301439
*def_node_id,
14311440
span,

‎compiler/rustc_codegen_cranelift/src/common.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -413,11 +413,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
413413

414414
// Note: must be kept in sync with get_caller_location from cg_ssa
415415
pub(crate) fn get_caller_location(&mut self, mut source_info: mir::SourceInfo) -> CValue<'tcx> {
416-
let span_to_caller_location = |fx: &mut FunctionCx<'_, '_, 'tcx>, mut span: Span| {
417-
// Remove `Inlined` marks as they pollute `expansion_cause`.
418-
while span.is_inlined() {
419-
span.remove_mark();
420-
}
416+
let span_to_caller_location = |fx: &mut FunctionCx<'_, '_, 'tcx>, span: Span| {
421417
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
422418
let caller = fx.tcx.sess.source_map().lookup_char_pos(topmost.lo());
423419
let const_loc = fx.tcx.const_caller_location((

‎compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,11 +1450,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
14501450
) -> OperandRef<'tcx, Bx::Value> {
14511451
let tcx = bx.tcx();
14521452

1453-
let mut span_to_caller_location = |mut span: Span| {
1454-
// Remove `Inlined` marks as they pollute `expansion_cause`.
1455-
while span.is_inlined() {
1456-
span.remove_mark();
1457-
}
1453+
let mut span_to_caller_location = |span: Span| {
14581454
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
14591455
let caller = tcx.sess.source_map().lookup_char_pos(topmost.lo());
14601456
let const_loc = tcx.const_caller_location((

‎compiler/rustc_const_eval/src/interpret/eval_context.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
949949
// This deliberately does *not* honor `requires_caller_location` since it is used for much
950950
// more than just panics.
951951
for frame in stack.iter().rev() {
952-
let span = frame.current_span();
952+
let span = match frame.loc {
953+
Left(loc) => {
954+
// If the stacktrace passes through MIR-inlined source scopes, add them.
955+
let mir::SourceInfo { mut span, scope } = *frame.body.source_info(loc);
956+
let mut scope_data = &frame.body.source_scopes[scope];
957+
while let Some((instance, call_span)) = scope_data.inlined {
958+
frames.push(FrameInfo { span, instance });
959+
span = call_span;
960+
scope_data = &frame.body.source_scopes[scope_data.parent_scope.unwrap()];
961+
}
962+
span
963+
}
964+
Right(span) => span,
965+
};
953966
frames.push(FrameInfo { span, instance: frame.instance });
954967
}
955968
trace!("generate stacktrace: {:#?}", frames);

‎compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
111111
location
112112
}
113113

114-
pub(crate) fn location_triple_for_span(&self, mut span: Span) -> (Symbol, u32, u32) {
115-
// Remove `Inlined` marks as they pollute `expansion_cause`.
116-
while span.is_inlined() {
117-
span.remove_mark();
118-
}
114+
pub(crate) fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) {
119115
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
120116
let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());
121117
(

‎compiler/rustc_errors/src/emitter.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ pub trait Emitter: Translate {
332332

333333
// Skip past non-macro entries, just in case there
334334
// are some which do actually involve macros.
335-
ExpnKind::Inlined | ExpnKind::Desugaring(..) | ExpnKind::AstPass(..) => None,
335+
ExpnKind::Desugaring(..) | ExpnKind::AstPass(..) => None,
336336

337337
ExpnKind::Macro(macro_kind, name) => Some((macro_kind, name)),
338338
}
@@ -403,7 +403,7 @@ pub trait Emitter: Translate {
403403
continue;
404404
}
405405

406-
if always_backtrace && !matches!(trace.kind, ExpnKind::Inlined) {
406+
if always_backtrace {
407407
new_labels.push((
408408
trace.def_site,
409409
format!(
@@ -442,7 +442,6 @@ pub trait Emitter: Translate {
442442
"this derive macro expansion".into()
443443
}
444444
ExpnKind::Macro(MacroKind::Bang, _) => "this macro invocation".into(),
445-
ExpnKind::Inlined => "this inlined function call".into(),
446445
ExpnKind::Root => "the crate root".into(),
447446
ExpnKind::AstPass(kind) => kind.descr().into(),
448447
ExpnKind::Desugaring(kind) => {

‎compiler/rustc_hir_typeck/src/expr_use_visitor.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -438,12 +438,19 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
438438
// to borrow discr.
439439
needs_to_be_read = true;
440440
}
441-
PatKind::Or(_)
442-
| PatKind::Box(_)
443-
| PatKind::Slice(..)
444-
| PatKind::Ref(..)
445-
| PatKind::Wild => {
446-
// If the PatKind is Or, Box, Slice or Ref, the decision is made later
441+
PatKind::Slice(lhs, wild, rhs) => {
442+
// We don't need to test the length if the pattern is `[..]`
443+
if matches!((lhs, wild, rhs), (&[], Some(_), &[]))
444+
// Arrays have a statically known size, so
445+
// there is no need to read their length
446+
|| discr_place.place.base_ty.is_array()
447+
{
448+
} else {
449+
needs_to_be_read = true;
450+
}
451+
}
452+
PatKind::Or(_) | PatKind::Box(_) | PatKind::Ref(..) | PatKind::Wild => {
453+
// If the PatKind is Or, Box, or Ref, the decision is made later
447454
// as these patterns contains subpatterns
448455
// If the PatKind is Wild, the decision is made based on the other patterns being
449456
// examined

‎compiler/rustc_lint/src/late.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,10 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
240240
}
241241

242242
fn visit_arm(&mut self, a: &'tcx hir::Arm<'tcx>) {
243-
lint_callback!(self, check_arm, a);
244-
hir_visit::walk_arm(self, a);
243+
self.with_lint_attrs(a.hir_id, |cx| {
244+
lint_callback!(cx, check_arm, a);
245+
hir_visit::walk_arm(cx, a);
246+
})
245247
}
246248

247249
fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {

‎compiler/rustc_middle/src/lint.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,8 +468,7 @@ pub fn struct_lint_level(
468468
pub fn in_external_macro(sess: &Session, span: Span) -> bool {
469469
let expn_data = span.ctxt().outer_expn_data();
470470
match expn_data.kind {
471-
ExpnKind::Inlined
472-
| ExpnKind::Root
471+
ExpnKind::Root
473472
| ExpnKind::Desugaring(
474473
DesugaringKind::ForLoop | DesugaringKind::WhileLoop | DesugaringKind::OpaqueTy,
475474
) => false,

‎compiler/rustc_middle/src/ty/mod.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2488,9 +2488,7 @@ impl<'tcx> TyCtxt<'tcx> {
24882488
&& if self.features().collapse_debuginfo {
24892489
span.in_macro_expansion_with_collapse_debuginfo()
24902490
} else {
2491-
// Inlined spans should not be collapsed as that leads to all of the
2492-
// inlined code being attributed to the inline callsite.
2493-
span.from_expansion() && !span.is_inlined()
2491+
span.from_expansion()
24942492
}
24952493
}
24962494

‎compiler/rustc_mir_build/src/thir/pattern/check_match.rs

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -90,35 +90,34 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for MatchVisitor<'a, '_, 'tcx> {
9090

9191
#[instrument(level = "trace", skip(self))]
9292
fn visit_arm(&mut self, arm: &Arm<'tcx>) {
93-
match arm.guard {
94-
Some(Guard::If(expr)) => {
95-
self.with_let_source(LetSource::IfLetGuard, |this| {
96-
this.visit_expr(&this.thir[expr])
97-
});
98-
}
99-
Some(Guard::IfLet(ref pat, expr)) => {
100-
self.with_let_source(LetSource::IfLetGuard, |this| {
101-
this.check_let(pat, expr, LetSource::IfLetGuard, pat.span);
102-
this.visit_pat(pat);
103-
this.visit_expr(&this.thir[expr]);
104-
});
93+
self.with_lint_level(arm.lint_level, |this| {
94+
match arm.guard {
95+
Some(Guard::If(expr)) => {
96+
this.with_let_source(LetSource::IfLetGuard, |this| {
97+
this.visit_expr(&this.thir[expr])
98+
});
99+
}
100+
Some(Guard::IfLet(ref pat, expr)) => {
101+
this.with_let_source(LetSource::IfLetGuard, |this| {
102+
this.check_let(pat, expr, LetSource::IfLetGuard, pat.span);
103+
this.visit_pat(pat);
104+
this.visit_expr(&this.thir[expr]);
105+
});
106+
}
107+
None => {}
105108
}
106-
None => {}
107-
}
108-
self.visit_pat(&arm.pattern);
109-
self.visit_expr(&self.thir[arm.body]);
109+
this.visit_pat(&arm.pattern);
110+
this.visit_expr(&self.thir[arm.body]);
111+
});
110112
}
111113

112114
#[instrument(level = "trace", skip(self))]
113115
fn visit_expr(&mut self, ex: &Expr<'tcx>) {
114116
match ex.kind {
115117
ExprKind::Scope { value, lint_level, .. } => {
116-
let old_lint_level = self.lint_level;
117-
if let LintLevel::Explicit(hir_id) = lint_level {
118-
self.lint_level = hir_id;
119-
}
120-
self.visit_expr(&self.thir[value]);
121-
self.lint_level = old_lint_level;
118+
self.with_lint_level(lint_level, |this| {
119+
this.visit_expr(&this.thir[value]);
120+
});
122121
return;
123122
}
124123
ExprKind::If { cond, then, else_opt, if_then_scope: _ } => {
@@ -190,6 +189,17 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
190189
self.let_source = old_let_source;
191190
}
192191

192+
fn with_lint_level(&mut self, new_lint_level: LintLevel, f: impl FnOnce(&mut Self)) {
193+
if let LintLevel::Explicit(hir_id) = new_lint_level {
194+
let old_lint_level = self.lint_level;
195+
self.lint_level = hir_id;
196+
f(self);
197+
self.lint_level = old_lint_level;
198+
} else {
199+
f(self);
200+
}
201+
}
202+
193203
fn check_patterns(&self, pat: &Pat<'tcx>, rf: RefutableFlag) {
194204
pat.walk_always(|pat| check_borrow_conflicts_in_at_patterns(self, pat));
195205
check_for_bindings_named_same_as_variants(self, pat, rf);
@@ -236,7 +246,9 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
236246
for &arm in arms {
237247
// Check the arm for some things unrelated to exhaustiveness.
238248
let arm = &self.thir.arms[arm];
239-
self.check_patterns(&arm.pattern, Refutable);
249+
self.with_lint_level(arm.lint_level, |this| {
250+
this.check_patterns(&arm.pattern, Refutable);
251+
});
240252
}
241253

242254
let tarms: Vec<_> = arms

‎compiler/rustc_mir_transform/src/inline.rs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use rustc_middle::mir::*;
1010
use rustc_middle::ty::TypeVisitableExt;
1111
use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
1212
use rustc_session::config::OptLevel;
13-
use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span};
1413
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
1514
use rustc_target::spec::abi::Abi;
1615

@@ -551,16 +550,6 @@ impl<'tcx> Inliner<'tcx> {
551550
// Copy the arguments if needed.
552551
let args: Vec<_> = self.make_call_args(args, &callsite, caller_body, &callee_body);
553552

554-
let mut expn_data = ExpnData::default(
555-
ExpnKind::Inlined,
556-
callsite.source_info.span,
557-
self.tcx.sess.edition(),
558-
None,
559-
None,
560-
);
561-
expn_data.def_site = callee_body.span;
562-
let expn_data =
563-
self.tcx.with_stable_hashing_context(|hcx| LocalExpnId::fresh(expn_data, hcx));
564553
let mut integrator = Integrator {
565554
args: &args,
566555
new_locals: Local::new(caller_body.local_decls.len())..,
@@ -572,7 +561,6 @@ impl<'tcx> Inliner<'tcx> {
572561
cleanup_block: unwind,
573562
in_cleanup_block: false,
574563
tcx: self.tcx,
575-
expn_data,
576564
always_live_locals: BitSet::new_filled(callee_body.local_decls.len()),
577565
};
578566

@@ -956,7 +944,6 @@ struct Integrator<'a, 'tcx> {
956944
cleanup_block: UnwindAction,
957945
in_cleanup_block: bool,
958946
tcx: TyCtxt<'tcx>,
959-
expn_data: LocalExpnId,
960947
always_live_locals: BitSet<Local>,
961948
}
962949

@@ -1042,11 +1029,6 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> {
10421029
*scope = self.map_scope(*scope);
10431030
}
10441031

1045-
fn visit_span(&mut self, span: &mut Span) {
1046-
// Make sure that all spans track the fact that they were inlined.
1047-
*span = span.fresh_expansion(self.expn_data);
1048-
}
1049-
10501032
fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) {
10511033
self.in_cleanup_block = data.is_cleanup;
10521034
self.super_basic_block_data(block, data);

‎compiler/rustc_resolve/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ edition = "2021"
77

88
[dependencies]
99
bitflags = "1.2.1"
10-
pulldown-cmark = { version = "0.9.2", default-features = false }
10+
pulldown-cmark = { version = "0.9.3", default-features = false }
1111
rustc_arena = { path = "../rustc_arena" }
1212
rustc_ast = { path = "../rustc_ast" }
1313
rustc_ast_pretty = { path = "../rustc_ast_pretty" }

‎compiler/rustc_span/src/hygiene.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,6 @@ impl ExpnId {
320320
// Stop going up the backtrace once include! is encountered
321321
if expn_data.is_root()
322322
|| expn_data.kind == ExpnKind::Macro(MacroKind::Bang, sym::include)
323-
|| expn_data.kind == ExpnKind::Inlined
324323
{
325324
break;
326325
}
@@ -1058,8 +1057,6 @@ pub enum ExpnKind {
10581057
AstPass(AstPass),
10591058
/// Desugaring done by the compiler during HIR lowering.
10601059
Desugaring(DesugaringKind),
1061-
/// MIR inlining
1062-
Inlined,
10631060
}
10641061

10651062
impl ExpnKind {
@@ -1073,7 +1070,6 @@ impl ExpnKind {
10731070
},
10741071
ExpnKind::AstPass(kind) => kind.descr().to_string(),
10751072
ExpnKind::Desugaring(kind) => format!("desugaring of {}", kind.descr()),
1076-
ExpnKind::Inlined => "inlined source".to_string(),
10771073
}
10781074
}
10791075
}

‎compiler/rustc_span/src/lib.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -594,12 +594,6 @@ impl Span {
594594
matches!(outer_expn.kind, ExpnKind::Macro(..)) && outer_expn.collapse_debuginfo
595595
}
596596

597-
/// Returns `true` if this span comes from MIR inlining.
598-
pub fn is_inlined(self) -> bool {
599-
let outer_expn = self.ctxt().outer_expn_data();
600-
matches!(outer_expn.kind, ExpnKind::Inlined)
601-
}
602-
603597
/// Returns `true` if `span` originates in a derive-macro's expansion.
604598
pub fn in_derive_expansion(self) -> bool {
605599
matches!(self.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _))

‎library/core/src/slice/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ mod index;
4242
mod iter;
4343
mod raw;
4444
mod rotate;
45+
mod select;
4546
mod specialize;
4647

4748
#[unstable(feature = "str_internals", issue = "none")]
@@ -3034,7 +3035,7 @@ impl<T> [T] {
30343035
where
30353036
T: Ord,
30363037
{
3037-
sort::partition_at_index(self, index, T::lt)
3038+
select::partition_at_index(self, index, T::lt)
30383039
}
30393040

30403041
/// Reorder the slice with a comparator function such that the element at `index` is at its
@@ -3089,7 +3090,7 @@ impl<T> [T] {
30893090
where
30903091
F: FnMut(&T, &T) -> Ordering,
30913092
{
3092-
sort::partition_at_index(self, index, |a: &T, b: &T| compare(a, b) == Less)
3093+
select::partition_at_index(self, index, |a: &T, b: &T| compare(a, b) == Less)
30933094
}
30943095

30953096
/// Reorder the slice with a key extraction function such that the element at `index` is at its
@@ -3145,7 +3146,7 @@ impl<T> [T] {
31453146
F: FnMut(&T) -> K,
31463147
K: Ord,
31473148
{
3148-
sort::partition_at_index(self, index, |a: &T, b: &T| f(a).lt(&f(b)))
3149+
select::partition_at_index(self, index, |a: &T, b: &T| f(a).lt(&f(b)))
31493150
}
31503151

31513152
/// Moves all consecutive repeated elements to the end of the slice according to the

‎library/core/src/slice/select.rs

Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
//! Slice selection
2+
//!
3+
//! This module contains the implementation for `slice::select_nth_unstable`.
4+
//! It uses an introselect algorithm based on Orson Peters' pattern-defeating quicksort,
5+
//! published at: <https://github.com/orlp/pdqsort>
6+
//!
7+
//! The fallback algorithm used for introselect is Median of Medians using Tukey's Ninther
8+
//! for pivot selection. Using this as a fallback ensures O(n) worst case running time with
9+
//! better performance than one would get using heapsort as fallback.
10+
11+
use crate::cmp;
12+
use crate::mem::{self, SizedTypeProperties};
13+
use crate::slice::sort::{
14+
break_patterns, choose_pivot, insertion_sort_shift_left, partition, partition_equal,
15+
};
16+
17+
// For slices of up to this length it's probably faster to simply sort them.
18+
// Defined at the module scope because it's used in multiple functions.
19+
const MAX_INSERTION: usize = 10;
20+
21+
fn partition_at_index_loop<'a, T, F>(
22+
mut v: &'a mut [T],
23+
mut index: usize,
24+
is_less: &mut F,
25+
mut pred: Option<&'a T>,
26+
) where
27+
F: FnMut(&T, &T) -> bool,
28+
{
29+
// Limit the amount of iterations and fall back to fast deterministic selection
30+
// to ensure O(n) worst case running time. This limit needs to be constant, because
31+
// using `ilog2(len)` like in `sort` would result in O(n log n) time complexity.
32+
// The exact value of the limit is chosen somewhat arbitrarily, but for most inputs bad pivot
33+
// selections should be relatively rare, so the limit usually shouldn't be reached
34+
// anyways.
35+
let mut limit = 16;
36+
37+
// True if the last partitioning was reasonably balanced.
38+
let mut was_balanced = true;
39+
40+
loop {
41+
if v.len() <= MAX_INSERTION {
42+
if v.len() > 1 {
43+
insertion_sort_shift_left(v, 1, is_less);
44+
}
45+
return;
46+
}
47+
48+
if limit == 0 {
49+
median_of_medians(v, is_less, index);
50+
return;
51+
}
52+
53+
// If the last partitioning was imbalanced, try breaking patterns in the slice by shuffling
54+
// some elements around. Hopefully we'll choose a better pivot this time.
55+
if !was_balanced {
56+
break_patterns(v);
57+
limit -= 1;
58+
}
59+
60+
// Choose a pivot
61+
let (pivot, _) = choose_pivot(v, is_less);
62+
63+
// If the chosen pivot is equal to the predecessor, then it's the smallest element in the
64+
// slice. Partition the slice into elements equal to and elements greater than the pivot.
65+
// This case is usually hit when the slice contains many duplicate elements.
66+
if let Some(p) = pred {
67+
if !is_less(p, &v[pivot]) {
68+
let mid = partition_equal(v, pivot, is_less);
69+
70+
// If we've passed our index, then we're good.
71+
if mid > index {
72+
return;
73+
}
74+
75+
// Otherwise, continue sorting elements greater than the pivot.
76+
v = &mut v[mid..];
77+
index = index - mid;
78+
pred = None;
79+
continue;
80+
}
81+
}
82+
83+
let (mid, _) = partition(v, pivot, is_less);
84+
was_balanced = cmp::min(mid, v.len() - mid) >= v.len() / 8;
85+
86+
// Split the slice into `left`, `pivot`, and `right`.
87+
let (left, right) = v.split_at_mut(mid);
88+
let (pivot, right) = right.split_at_mut(1);
89+
let pivot = &pivot[0];
90+
91+
if mid < index {
92+
v = right;
93+
index = index - mid - 1;
94+
pred = Some(pivot);
95+
} else if mid > index {
96+
v = left;
97+
} else {
98+
// If mid == index, then we're done, since partition() guaranteed that all elements
99+
// after mid are greater than or equal to mid.
100+
return;
101+
}
102+
}
103+
}
104+
105+
/// Helper function that returns the index of the minimum element in the slice using the given
106+
/// comparator function
107+
fn min_index<T, F: FnMut(&T, &T) -> bool>(slice: &[T], is_less: &mut F) -> Option<usize> {
108+
slice
109+
.iter()
110+
.enumerate()
111+
.reduce(|acc, t| if is_less(t.1, acc.1) { t } else { acc })
112+
.map(|(i, _)| i)
113+
}
114+
115+
/// Helper function that returns the index of the maximum element in the slice using the given
116+
/// comparator function
117+
fn max_index<T, F: FnMut(&T, &T) -> bool>(slice: &[T], is_less: &mut F) -> Option<usize> {
118+
slice
119+
.iter()
120+
.enumerate()
121+
.reduce(|acc, t| if is_less(acc.1, t.1) { t } else { acc })
122+
.map(|(i, _)| i)
123+
}
124+
125+
/// Reorder the slice such that the element at `index` is at its final sorted position.
126+
pub fn partition_at_index<T, F>(
127+
v: &mut [T],
128+
index: usize,
129+
mut is_less: F,
130+
) -> (&mut [T], &mut T, &mut [T])
131+
where
132+
F: FnMut(&T, &T) -> bool,
133+
{
134+
if index >= v.len() {
135+
panic!("partition_at_index index {} greater than length of slice {}", index, v.len());
136+
}
137+
138+
if T::IS_ZST {
139+
// Sorting has no meaningful behavior on zero-sized types. Do nothing.
140+
} else if index == v.len() - 1 {
141+
// Find max element and place it in the last position of the array. We're free to use
142+
// `unwrap()` here because we know v must not be empty.
143+
let max_idx = max_index(v, &mut is_less).unwrap();
144+
v.swap(max_idx, index);
145+
} else if index == 0 {
146+
// Find min element and place it in the first position of the array. We're free to use
147+
// `unwrap()` here because we know v must not be empty.
148+
let min_idx = min_index(v, &mut is_less).unwrap();
149+
v.swap(min_idx, index);
150+
} else {
151+
partition_at_index_loop(v, index, &mut is_less, None);
152+
}
153+
154+
let (left, right) = v.split_at_mut(index);
155+
let (pivot, right) = right.split_at_mut(1);
156+
let pivot = &mut pivot[0];
157+
(left, pivot, right)
158+
}
159+
160+
/// Selection algorithm to select the k-th element from the slice in guaranteed O(n) time.
161+
/// This is essentially a quickselect that uses Tukey's Ninther for pivot selection
162+
fn median_of_medians<T, F: FnMut(&T, &T) -> bool>(mut v: &mut [T], is_less: &mut F, mut k: usize) {
163+
// Since this function isn't public, it should never be called with an out-of-bounds index.
164+
debug_assert!(k < v.len());
165+
166+
// If T is as ZST, `partition_at_index` will already return early.
167+
debug_assert!(!T::IS_ZST);
168+
169+
// We now know that `k < v.len() <= isize::MAX`
170+
loop {
171+
if v.len() <= MAX_INSERTION {
172+
if v.len() > 1 {
173+
insertion_sort_shift_left(v, 1, is_less);
174+
}
175+
return;
176+
}
177+
178+
// `median_of_{minima,maxima}` can't handle the extreme cases of the first/last element,
179+
// so we catch them here and just do a linear search.
180+
if k == v.len() - 1 {
181+
// Find max element and place it in the last position of the array. We're free to use
182+
// `unwrap()` here because we know v must not be empty.
183+
let max_idx = max_index(v, is_less).unwrap();
184+
v.swap(max_idx, k);
185+
return;
186+
} else if k == 0 {
187+
// Find min element and place it in the first position of the array. We're free to use
188+
// `unwrap()` here because we know v must not be empty.
189+
let min_idx = min_index(v, is_less).unwrap();
190+
v.swap(min_idx, k);
191+
return;
192+
}
193+
194+
let p = median_of_ninthers(v, is_less);
195+
196+
if p == k {
197+
return;
198+
} else if p > k {
199+
v = &mut v[..p];
200+
} else {
201+
// Since `p < k < v.len()`, `p + 1` doesn't overflow and is
202+
// a valid index into the slice.
203+
v = &mut v[p + 1..];
204+
k -= p + 1;
205+
}
206+
}
207+
}
208+
209+
// Optimized for when `k` lies somewhere in the middle of the slice. Selects a pivot
210+
// as close as possible to the median of the slice. For more details on how the algorithm
211+
// operates, refer to the paper <https://drops.dagstuhl.de/opus/volltexte/2017/7612/pdf/LIPIcs-SEA-2017-24.pdf>.
212+
fn median_of_ninthers<T, F: FnMut(&T, &T) -> bool>(v: &mut [T], is_less: &mut F) -> usize {
213+
// use `saturating_mul` so the multiplication doesn't overflow on 16-bit platforms.
214+
let frac = if v.len() <= 1024 {
215+
v.len() / 12
216+
} else if v.len() <= 128_usize.saturating_mul(1024) {
217+
v.len() / 64
218+
} else {
219+
v.len() / 1024
220+
};
221+
222+
let pivot = frac / 2;
223+
let lo = v.len() / 2 - pivot;
224+
let hi = frac + lo;
225+
let gap = (v.len() - 9 * frac) / 4;
226+
let mut a = lo - 4 * frac - gap;
227+
let mut b = hi + gap;
228+
for i in lo..hi {
229+
ninther(v, is_less, a, i - frac, b, a + 1, i, b + 1, a + 2, i + frac, b + 2);
230+
a += 3;
231+
b += 3;
232+
}
233+
234+
median_of_medians(&mut v[lo..lo + frac], is_less, pivot);
235+
partition(v, lo + pivot, is_less).0
236+
}
237+
238+
/// Moves around the 9 elements at the indices a..i, such that
239+
/// `v[d]` contains the median of the 9 elements and the other
240+
/// elements are partitioned around it.
241+
fn ninther<T, F: FnMut(&T, &T) -> bool>(
242+
v: &mut [T],
243+
is_less: &mut F,
244+
a: usize,
245+
mut b: usize,
246+
c: usize,
247+
mut d: usize,
248+
e: usize,
249+
mut f: usize,
250+
g: usize,
251+
mut h: usize,
252+
i: usize,
253+
) {
254+
b = median_idx(v, is_less, a, b, c);
255+
h = median_idx(v, is_less, g, h, i);
256+
if is_less(&v[h], &v[b]) {
257+
mem::swap(&mut b, &mut h);
258+
}
259+
if is_less(&v[f], &v[d]) {
260+
mem::swap(&mut d, &mut f);
261+
}
262+
if is_less(&v[e], &v[d]) {
263+
// do nothing
264+
} else if is_less(&v[f], &v[e]) {
265+
d = f;
266+
} else {
267+
if is_less(&v[e], &v[b]) {
268+
v.swap(e, b);
269+
} else if is_less(&v[h], &v[e]) {
270+
v.swap(e, h);
271+
}
272+
return;
273+
}
274+
if is_less(&v[d], &v[b]) {
275+
d = b;
276+
} else if is_less(&v[h], &v[d]) {
277+
d = h;
278+
}
279+
280+
v.swap(d, e);
281+
}
282+
283+
/// returns the index pointing to the median of the 3
284+
/// elements `v[a]`, `v[b]` and `v[c]`
285+
fn median_idx<T, F: FnMut(&T, &T) -> bool>(
286+
v: &[T],
287+
is_less: &mut F,
288+
mut a: usize,
289+
b: usize,
290+
mut c: usize,
291+
) -> usize {
292+
if is_less(&v[c], &v[a]) {
293+
mem::swap(&mut a, &mut c);
294+
}
295+
if is_less(&v[c], &v[b]) {
296+
return c;
297+
}
298+
if is_less(&v[b], &v[a]) {
299+
return a;
300+
}
301+
b
302+
}

‎library/core/src/slice/sort.rs

Lines changed: 5 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ where
145145
/// Never inline this function to avoid code bloat. It still optimizes nicely and has practically no
146146
/// performance impact. Even improving performance in some cases.
147147
#[inline(never)]
148-
fn insertion_sort_shift_left<T, F>(v: &mut [T], offset: usize, is_less: &mut F)
148+
pub(super) fn insertion_sort_shift_left<T, F>(v: &mut [T], offset: usize, is_less: &mut F)
149149
where
150150
F: FnMut(&T, &T) -> bool,
151151
{
@@ -557,7 +557,7 @@ where
557557
///
558558
/// 1. Number of elements smaller than `v[pivot]`.
559559
/// 2. True if `v` was already partitioned.
560-
fn partition<T, F>(v: &mut [T], pivot: usize, is_less: &mut F) -> (usize, bool)
560+
pub(super) fn partition<T, F>(v: &mut [T], pivot: usize, is_less: &mut F) -> (usize, bool)
561561
where
562562
F: FnMut(&T, &T) -> bool,
563563
{
@@ -612,7 +612,7 @@ where
612612
///
613613
/// Returns the number of elements equal to the pivot. It is assumed that `v` does not contain
614614
/// elements smaller than the pivot.
615-
fn partition_equal<T, F>(v: &mut [T], pivot: usize, is_less: &mut F) -> usize
615+
pub(super) fn partition_equal<T, F>(v: &mut [T], pivot: usize, is_less: &mut F) -> usize
616616
where
617617
F: FnMut(&T, &T) -> bool,
618618
{
@@ -670,7 +670,7 @@ where
670670
/// Scatters some elements around in an attempt to break patterns that might cause imbalanced
671671
/// partitions in quicksort.
672672
#[cold]
673-
fn break_patterns<T>(v: &mut [T]) {
673+
pub(super) fn break_patterns<T>(v: &mut [T]) {
674674
let len = v.len();
675675
if len >= 8 {
676676
let mut seed = len;
@@ -719,7 +719,7 @@ fn break_patterns<T>(v: &mut [T]) {
719719
/// Chooses a pivot in `v` and returns the index and `true` if the slice is likely already sorted.
720720
///
721721
/// Elements in `v` might be reordered in the process.
722-
fn choose_pivot<T, F>(v: &mut [T], is_less: &mut F) -> (usize, bool)
722+
pub(super) fn choose_pivot<T, F>(v: &mut [T], is_less: &mut F) -> (usize, bool)
723723
where
724724
F: FnMut(&T, &T) -> bool,
725725
{
@@ -897,138 +897,6 @@ where
897897
recurse(v, &mut is_less, None, limit);
898898
}
899899

900-
fn partition_at_index_loop<'a, T, F>(
901-
mut v: &'a mut [T],
902-
mut index: usize,
903-
is_less: &mut F,
904-
mut pred: Option<&'a T>,
905-
) where
906-
F: FnMut(&T, &T) -> bool,
907-
{
908-
// Limit the amount of iterations and fall back to heapsort, similarly to `slice::sort_unstable`.
909-
// This lowers the worst case running time from O(n^2) to O(n log n).
910-
// FIXME: Investigate whether it would be better to use something like Median of Medians
911-
// or Fast Deterministic Selection to guarantee O(n) worst case.
912-
let mut limit = usize::BITS - v.len().leading_zeros();
913-
914-
// True if the last partitioning was reasonably balanced.
915-
let mut was_balanced = true;
916-
917-
loop {
918-
let len = v.len();
919-
920-
// For slices of up to this length it's probably faster to simply sort them.
921-
const MAX_INSERTION: usize = 10;
922-
if len <= MAX_INSERTION {
923-
if len >= 2 {
924-
insertion_sort_shift_left(v, 1, is_less);
925-
}
926-
return;
927-
}
928-
929-
if limit == 0 {
930-
heapsort(v, is_less);
931-
return;
932-
}
933-
934-
// If the last partitioning was imbalanced, try breaking patterns in the slice by shuffling
935-
// some elements around. Hopefully we'll choose a better pivot this time.
936-
if !was_balanced {
937-
break_patterns(v);
938-
limit -= 1;
939-
}
940-
941-
// Choose a pivot
942-
let (pivot, _) = choose_pivot(v, is_less);
943-
944-
// If the chosen pivot is equal to the predecessor, then it's the smallest element in the
945-
// slice. Partition the slice into elements equal to and elements greater than the pivot.
946-
// This case is usually hit when the slice contains many duplicate elements.
947-
if let Some(p) = pred {
948-
if !is_less(p, &v[pivot]) {
949-
let mid = partition_equal(v, pivot, is_less);
950-
951-
// If we've passed our index, then we're good.
952-
if mid > index {
953-
return;
954-
}
955-
956-
// Otherwise, continue sorting elements greater than the pivot.
957-
v = &mut v[mid..];
958-
index = index - mid;
959-
pred = None;
960-
continue;
961-
}
962-
}
963-
964-
let (mid, _) = partition(v, pivot, is_less);
965-
was_balanced = cmp::min(mid, len - mid) >= len / 8;
966-
967-
// Split the slice into `left`, `pivot`, and `right`.
968-
let (left, right) = v.split_at_mut(mid);
969-
let (pivot, right) = right.split_at_mut(1);
970-
let pivot = &pivot[0];
971-
972-
if mid < index {
973-
v = right;
974-
index = index - mid - 1;
975-
pred = Some(pivot);
976-
} else if mid > index {
977-
v = left;
978-
} else {
979-
// If mid == index, then we're done, since partition() guaranteed that all elements
980-
// after mid are greater than or equal to mid.
981-
return;
982-
}
983-
}
984-
}
985-
986-
/// Reorder the slice such that the element at `index` is at its final sorted position.
987-
pub fn partition_at_index<T, F>(
988-
v: &mut [T],
989-
index: usize,
990-
mut is_less: F,
991-
) -> (&mut [T], &mut T, &mut [T])
992-
where
993-
F: FnMut(&T, &T) -> bool,
994-
{
995-
use cmp::Ordering::Greater;
996-
use cmp::Ordering::Less;
997-
998-
if index >= v.len() {
999-
panic!("partition_at_index index {} greater than length of slice {}", index, v.len());
1000-
}
1001-
1002-
if T::IS_ZST {
1003-
// Sorting has no meaningful behavior on zero-sized types. Do nothing.
1004-
} else if index == v.len() - 1 {
1005-
// Find max element and place it in the last position of the array. We're free to use
1006-
// `unwrap()` here because we know v must not be empty.
1007-
let (max_index, _) = v
1008-
.iter()
1009-
.enumerate()
1010-
.max_by(|&(_, x), &(_, y)| if is_less(x, y) { Less } else { Greater })
1011-
.unwrap();
1012-
v.swap(max_index, index);
1013-
} else if index == 0 {
1014-
// Find min element and place it in the first position of the array. We're free to use
1015-
// `unwrap()` here because we know v must not be empty.
1016-
let (min_index, _) = v
1017-
.iter()
1018-
.enumerate()
1019-
.min_by(|&(_, x), &(_, y)| if is_less(x, y) { Less } else { Greater })
1020-
.unwrap();
1021-
v.swap(min_index, index);
1022-
} else {
1023-
partition_at_index_loop(v, index, &mut is_less, None);
1024-
}
1025-
1026-
let (left, right) = v.split_at_mut(index);
1027-
let (pivot, right) = right.split_at_mut(1);
1028-
let pivot = &mut pivot[0];
1029-
(left, pivot, right)
1030-
}
1031-
1032900
/// Merges non-decreasing runs `v[..mid]` and `v[mid..]` using `buf` as temporary storage, and
1033901
/// stores the result into `v[..]`.
1034902
///

‎src/doc/rustdoc/src/how-to-write-documentation.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,15 +165,15 @@ extensions:
165165
### Strikethrough
166166

167167
Text may be rendered with a horizontal line through the center by wrapping the
168-
text with two tilde characters on each side:
168+
text with one or two tilde characters on each side:
169169

170170
```text
171-
An example of ~~strikethrough text~~.
171+
An example of ~~strikethrough text~~. You can also use ~single tildes~.
172172
```
173173

174174
This example will render as:
175175

176-
> An example of ~~strikethrough text~~.
176+
> An example of ~~strikethrough text~~. You can also use ~single tildes~.
177177
178178
This follows the [GitHub Strikethrough extension][strikethrough].
179179

‎src/tools/miri/tests/fail/terminate-terminator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ impl Drop for Foo {
1212

1313
#[inline(always)]
1414
fn has_cleanup() {
15+
//~^ ERROR: panic in a function that cannot unwind
1516
let _f = Foo;
1617
panic!();
1718
}
1819

1920
extern "C" fn panic_abort() {
2021
has_cleanup();
21-
//~^ ERROR: panic in a function that cannot unwind
2222
}
2323

2424
fn main() {

‎src/tools/miri/tests/fail/terminate-terminator.stderr

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@ error: abnormal termination: panic in a function that cannot unwind
66
--> $DIR/terminate-terminator.rs:LL:CC
77
|
88
LL | / fn has_cleanup() {
9+
LL | |
910
LL | | let _f = Foo;
1011
LL | | panic!();
1112
LL | | }
1213
| |_^ panic in a function that cannot unwind
13-
...
14-
LL | has_cleanup();
15-
| ------------- in this inlined function call
1614
|
17-
= note: inside `panic_abort` at $DIR/terminate-terminator.rs:LL:CC
15+
= note: inside `has_cleanup` at $DIR/terminate-terminator.rs:LL:CC
16+
note: inside `panic_abort`
17+
--> $DIR/terminate-terminator.rs:LL:CC
18+
|
19+
LL | has_cleanup();
20+
| ^^^^^^^^^^^^^
1821
note: inside `main`
1922
--> $DIR/terminate-terminator.rs:LL:CC
2023
|

‎tests/rustdoc-gui/highlight-colors.goml

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -43,52 +43,52 @@ define-function: (
4343

4444
call-function: ("check-colors", {
4545
"theme": "ayu",
46-
"kw": "rgb(255, 119, 51)",
47-
"kw2": "rgb(255, 119, 51)",
48-
"prelude_ty": "rgb(105, 242, 223)",
49-
"prelude_val": "rgb(255, 119, 51)",
50-
"lifetime": "rgb(255, 119, 51)",
51-
"number": "rgb(184, 204, 82)",
52-
"string": "rgb(184, 204, 82)",
53-
"bool_val": "rgb(255, 119, 51)",
54-
"self": "rgb(54, 163, 217)",
55-
"attr": "rgb(230, 225, 207)",
56-
"macro": "rgb(163, 122, 204)",
57-
"question_mark": "rgb(255, 144, 17)",
58-
"comment": "rgb(120, 135, 151)",
59-
"doc_comment": "rgb(161, 172, 136)",
46+
"kw": "#ff7733",
47+
"kw2": "#ff7733",
48+
"prelude_ty": "#69f2df",
49+
"prelude_val": "#ff7733",
50+
"lifetime": "#ff7733",
51+
"number": "#b8cc52",
52+
"string": "#b8cc52",
53+
"bool_val": "#ff7733",
54+
"self": "#36a3d9",
55+
"attr": "#e6e1cf",
56+
"macro": "#a37acc",
57+
"question_mark": "#ff9011",
58+
"comment": "#788797",
59+
"doc_comment": "#a1ac88",
6060
})
6161
call-function: ("check-colors", {
6262
"theme": "dark",
63-
"kw": "rgb(171, 138, 193)",
64-
"kw2": "rgb(118, 154, 203)",
65-
"prelude_ty": "rgb(118, 154, 203)",
66-
"prelude_val": "rgb(238, 104, 104)",
67-
"lifetime": "rgb(217, 127, 38)",
68-
"number": "rgb(131, 163, 0)",
69-
"string": "rgb(131, 163, 0)",
70-
"bool_val": "rgb(238, 104, 104)",
71-
"self": "rgb(238, 104, 104)",
72-
"attr": "rgb(238, 104, 104)",
73-
"macro": "rgb(62, 153, 159)",
74-
"question_mark": "rgb(255, 144, 17)",
75-
"comment": "rgb(141, 141, 139)",
76-
"doc_comment": "rgb(140, 163, 117)",
63+
"kw": "#ab8ac1",
64+
"kw2": "#769acb",
65+
"prelude_ty": "#769acb",
66+
"prelude_val": "#ee6868",
67+
"lifetime": "#d97f26",
68+
"number": "#83a300",
69+
"string": "#83a300",
70+
"bool_val": "#ee6868",
71+
"self": "#ee6868",
72+
"attr": "#ee6868",
73+
"macro": "#3e999f",
74+
"question_mark": "#ff9011",
75+
"comment": "#8d8d8b",
76+
"doc_comment": "#8ca375",
7777
})
7878
call-function: ("check-colors", {
7979
"theme": "light",
80-
"kw": "rgb(137, 89, 168)",
81-
"kw2": "rgb(66, 113, 174)",
82-
"prelude_ty": "rgb(66, 113, 174)",
83-
"prelude_val": "rgb(200, 40, 41)",
84-
"lifetime": "rgb(183, 101, 20)",
85-
"number": "rgb(113, 140, 0)",
86-
"string": "rgb(113, 140, 0)",
87-
"bool_val": "rgb(200, 40, 41)",
88-
"self": "rgb(200, 40, 41)",
89-
"attr": "rgb(200, 40, 41)",
90-
"macro": "rgb(62, 153, 159)",
91-
"question_mark": "rgb(255, 144, 17)",
92-
"comment": "rgb(142, 144, 140)",
93-
"doc_comment": "rgb(77, 77, 76)",
80+
"kw": "#8959a8",
81+
"kw2": "#4271ae",
82+
"prelude_ty": "#4271ae",
83+
"prelude_val": "#c82829",
84+
"lifetime": "#b76514",
85+
"number": "#718c00",
86+
"string": "#718c00",
87+
"bool_val": "#c82829",
88+
"self": "#c82829",
89+
"attr": "#c82829",
90+
"macro": "#3e999f",
91+
"question_mark": "#ff9011",
92+
"comment": "#8e908c",
93+
"doc_comment": "#4d4d4c",
9494
})

‎tests/rustdoc-ui/unescaped_backticks.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,3 +340,15 @@ id! {
340340
/// level changes.
341341
pub mod tracing_macro {}
342342
}
343+
344+
/// Regression test for <https://github.com/rust-lang/rust/issues/111117>
345+
pub mod trillium_server_common {
346+
/// One-indexed, because the first CloneCounter is included. If you don't
347+
/// want the original to count, construct a [``CloneCounterObserver`]
348+
/// instead and use [`CloneCounterObserver::counter`] to increment.
349+
//~^ ERROR unescaped backtick
350+
pub struct CloneCounter;
351+
352+
/// This is used by the above.
353+
pub struct CloneCounterObserver;
354+
}

‎tests/rustdoc-ui/unescaped_backticks.stderr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,18 @@ LL | | /// level changes.
341341
change: [`rebuild_interest_cache`][rebuild] is called after the value of the max
342342
to this: [`rebuild_interest_cache\`][rebuild] is called after the value of the max
343343

344+
error: unescaped backtick
345+
--> $DIR/unescaped_backticks.rs:348:56
346+
|
347+
LL | /// instead and use [`CloneCounterObserver::counter`] to increment.
348+
| ^
349+
|
350+
= help: the opening or closing backtick of an inline code may be missing
351+
help: if you meant to use a literal backtick, escape it
352+
|
353+
LL | /// instead and use [`CloneCounterObserver::counter\`] to increment.
354+
| +
355+
344356
error: unescaped backtick
345357
--> $DIR/unescaped_backticks.rs:11:5
346358
|
@@ -955,5 +967,5 @@ help: if you meant to use a literal backtick, escape it
955967
LL | /// | table`( | )\`body |
956968
| +
957969

958-
error: aborting due to 63 previous errors
970+
error: aborting due to 64 previous errors
959971

‎tests/rustdoc/strikethrough-in-summary.rs

Lines changed: 0 additions & 6 deletions
This file was deleted.

‎tests/rustdoc/test-strikethrough.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
#![crate_name = "foo"]
22

3-
// @has foo/fn.f.html
4-
// @has - //del "Y"
5-
/// ~~Y~~
3+
// Test that strikethrough works with single and double tildes and that it shows up on
4+
// the item's dedicated page as well as the parent module's summary of items.
5+
6+
// @has foo/index.html //del 'strike'
7+
// @has foo/index.html //del 'through'
8+
9+
// @has foo/fn.f.html //del 'strike'
10+
// @has foo/fn.f.html //del 'through'
11+
12+
/// ~~strike~~ ~through~
613
pub fn f() {}

‎tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
// edition:2021
22

33
#![feature(rustc_attrs)]
4+
#![feature(stmt_expr_attributes)]
45

56
// Should capture the discriminant since a variant of a multivariant enum is
67
// mentioned in the match arm; the discriminant is captured by the closure regardless
78
// of if it creates a binding
89
fn test_1_should_capture() {
910
let variant = Some(2229);
1011
let c = #[rustc_capture_analysis]
11-
//~^ ERROR: attributes on expressions are experimental
12-
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
13-
1412
|| {
1513
//~^ First Pass analysis includes:
1614
//~| Min Capture analysis includes:
@@ -29,8 +27,6 @@ fn test_1_should_capture() {
2927
fn test_2_should_not_capture() {
3028
let variant = Some(2229);
3129
let c = #[rustc_capture_analysis]
32-
//~^ ERROR: attributes on expressions are experimental
33-
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
3430
|| {
3531
//~^ First Pass analysis includes:
3632
match variant {
@@ -50,8 +46,6 @@ enum SingleVariant {
5046
fn test_3_should_not_capture_single_variant() {
5147
let variant = SingleVariant::Points(1);
5248
let c = #[rustc_capture_analysis]
53-
//~^ ERROR: attributes on expressions are experimental
54-
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
5549
|| {
5650
//~^ First Pass analysis includes:
5751
match variant {
@@ -66,8 +60,6 @@ fn test_3_should_not_capture_single_variant() {
6660
fn test_6_should_capture_single_variant() {
6761
let variant = SingleVariant::Points(1);
6862
let c = #[rustc_capture_analysis]
69-
//~^ ERROR: attributes on expressions are experimental
70-
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
7163
|| {
7264
//~^ First Pass analysis includes:
7365
//~| Min Capture analysis includes:
@@ -88,8 +80,6 @@ fn test_6_should_capture_single_variant() {
8880
fn test_4_should_not_capture_array() {
8981
let array: [i32; 3] = [0; 3];
9082
let c = #[rustc_capture_analysis]
91-
//~^ ERROR: attributes on expressions are experimental
92-
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
9383
|| {
9484
//~^ First Pass analysis includes:
9585
match array {
@@ -112,8 +102,6 @@ enum MVariant {
112102
fn test_5_should_capture_multi_variant() {
113103
let variant = MVariant::A;
114104
let c = #[rustc_capture_analysis]
115-
//~^ ERROR: attributes on expressions are experimental
116-
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
117105
|| {
118106
//~^ First Pass analysis includes:
119107
//~| Min Capture analysis includes:
@@ -127,11 +115,69 @@ fn test_5_should_capture_multi_variant() {
127115
c();
128116
}
129117

118+
// Even though all patterns are wild, we need to read the discriminant
119+
// in order to test the slice length
120+
fn test_7_should_capture_slice_len() {
121+
let slice: &[i32] = &[1, 2, 3];
122+
let c = #[rustc_capture_analysis]
123+
|| {
124+
//~^ First Pass analysis includes:
125+
//~| Min Capture analysis includes:
126+
match slice {
127+
//~^ NOTE: Capturing slice[] -> ImmBorrow
128+
//~| NOTE: Min Capture slice[] -> ImmBorrow
129+
[_,_,_] => {},
130+
_ => {}
131+
}
132+
};
133+
c();
134+
let c = #[rustc_capture_analysis]
135+
|| {
136+
//~^ First Pass analysis includes:
137+
//~| Min Capture analysis includes:
138+
match slice {
139+
//~^ NOTE: Capturing slice[] -> ImmBorrow
140+
//~| NOTE: Min Capture slice[] -> ImmBorrow
141+
[] => {},
142+
_ => {}
143+
}
144+
};
145+
c();
146+
let c = #[rustc_capture_analysis]
147+
|| {
148+
//~^ First Pass analysis includes:
149+
//~| Min Capture analysis includes:
150+
match slice {
151+
//~^ NOTE: Capturing slice[] -> ImmBorrow
152+
//~| NOTE: Min Capture slice[] -> ImmBorrow
153+
[_, .. ,_] => {},
154+
_ => {}
155+
}
156+
};
157+
c();
158+
}
159+
160+
// Wild pattern that doesn't bind, so no capture
161+
fn test_8_capture_slice_wild() {
162+
let slice: &[i32] = &[1, 2, 3];
163+
let c = #[rustc_capture_analysis]
164+
|| {
165+
//~^ First Pass analysis includes:
166+
match slice {
167+
[..] => {},
168+
_ => {}
169+
}
170+
};
171+
c();
172+
}
173+
130174
fn main() {
131175
test_1_should_capture();
132176
test_2_should_not_capture();
133177
test_3_should_not_capture_single_variant();
134178
test_6_should_capture_single_variant();
135179
test_4_should_not_capture_array();
136180
test_5_should_capture_multi_variant();
181+
test_7_should_capture_slice_len();
182+
test_8_capture_slice_wild();
137183
}

‎tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr

Lines changed: 137 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,5 @@
1-
error[E0658]: attributes on expressions are experimental
2-
--> $DIR/patterns-capture-analysis.rs:10:14
3-
|
4-
LL | let c = #[rustc_capture_analysis]
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6-
|
7-
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
8-
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
9-
10-
error[E0658]: attributes on expressions are experimental
11-
--> $DIR/patterns-capture-analysis.rs:31:14
12-
|
13-
LL | let c = #[rustc_capture_analysis]
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
15-
|
16-
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
17-
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
18-
19-
error[E0658]: attributes on expressions are experimental
20-
--> $DIR/patterns-capture-analysis.rs:52:14
21-
|
22-
LL | let c = #[rustc_capture_analysis]
23-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
24-
|
25-
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
26-
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
27-
28-
error[E0658]: attributes on expressions are experimental
29-
--> $DIR/patterns-capture-analysis.rs:68:14
30-
|
31-
LL | let c = #[rustc_capture_analysis]
32-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
33-
|
34-
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
35-
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
36-
37-
error[E0658]: attributes on expressions are experimental
38-
--> $DIR/patterns-capture-analysis.rs:90:14
39-
|
40-
LL | let c = #[rustc_capture_analysis]
41-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
42-
|
43-
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
44-
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
45-
46-
error[E0658]: attributes on expressions are experimental
47-
--> $DIR/patterns-capture-analysis.rs:114:14
48-
|
49-
LL | let c = #[rustc_capture_analysis]
50-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
51-
|
52-
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
53-
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
54-
551
error: First Pass analysis includes:
56-
--> $DIR/patterns-capture-analysis.rs:14:5
2+
--> $DIR/patterns-capture-analysis.rs:12:5
573
|
584
LL | / || {
595
LL | |
@@ -65,13 +11,13 @@ LL | | };
6511
| |_____^
6612
|
6713
note: Capturing variant[] -> ImmBorrow
68-
--> $DIR/patterns-capture-analysis.rs:17:15
14+
--> $DIR/patterns-capture-analysis.rs:15:15
6915
|
7016
LL | match variant {
7117
| ^^^^^^^
7218

7319
error: Min Capture analysis includes:
74-
--> $DIR/patterns-capture-analysis.rs:14:5
20+
--> $DIR/patterns-capture-analysis.rs:12:5
7521
|
7622
LL | / || {
7723
LL | |
@@ -83,13 +29,13 @@ LL | | };
8329
| |_____^
8430
|
8531
note: Min Capture variant[] -> ImmBorrow
86-
--> $DIR/patterns-capture-analysis.rs:17:15
32+
--> $DIR/patterns-capture-analysis.rs:15:15
8733
|
8834
LL | match variant {
8935
| ^^^^^^^
9036

9137
error: First Pass analysis includes:
92-
--> $DIR/patterns-capture-analysis.rs:34:5
38+
--> $DIR/patterns-capture-analysis.rs:30:5
9339
|
9440
LL | / || {
9541
LL | |
@@ -100,7 +46,7 @@ LL | | };
10046
| |_____^
10147

10248
error: First Pass analysis includes:
103-
--> $DIR/patterns-capture-analysis.rs:55:5
49+
--> $DIR/patterns-capture-analysis.rs:49:5
10450
|
10551
LL | / || {
10652
LL | |
@@ -111,7 +57,7 @@ LL | | };
11157
| |_____^
11258

11359
error: First Pass analysis includes:
114-
--> $DIR/patterns-capture-analysis.rs:71:5
60+
--> $DIR/patterns-capture-analysis.rs:63:5
11561
|
11662
LL | / || {
11763
LL | |
@@ -123,18 +69,18 @@ LL | | };
12369
| |_____^
12470
|
12571
note: Capturing variant[] -> ImmBorrow
126-
--> $DIR/patterns-capture-analysis.rs:74:15
72+
--> $DIR/patterns-capture-analysis.rs:66:15
12773
|
12874
LL | match variant {
12975
| ^^^^^^^
13076
note: Capturing variant[(0, 0)] -> ImmBorrow
131-
--> $DIR/patterns-capture-analysis.rs:74:15
77+
--> $DIR/patterns-capture-analysis.rs:66:15
13278
|
13379
LL | match variant {
13480
| ^^^^^^^
13581

13682
error: Min Capture analysis includes:
137-
--> $DIR/patterns-capture-analysis.rs:71:5
83+
--> $DIR/patterns-capture-analysis.rs:63:5
13884
|
13985
LL | / || {
14086
LL | |
@@ -146,13 +92,13 @@ LL | | };
14692
| |_____^
14793
|
14894
note: Min Capture variant[] -> ImmBorrow
149-
--> $DIR/patterns-capture-analysis.rs:74:15
95+
--> $DIR/patterns-capture-analysis.rs:66:15
15096
|
15197
LL | match variant {
15298
| ^^^^^^^
15399

154100
error: First Pass analysis includes:
155-
--> $DIR/patterns-capture-analysis.rs:93:5
101+
--> $DIR/patterns-capture-analysis.rs:83:5
156102
|
157103
LL | / || {
158104
LL | |
@@ -163,7 +109,7 @@ LL | | };
163109
| |_____^
164110

165111
error: First Pass analysis includes:
166-
--> $DIR/patterns-capture-analysis.rs:117:5
112+
--> $DIR/patterns-capture-analysis.rs:105:5
167113
|
168114
LL | / || {
169115
LL | |
@@ -175,13 +121,13 @@ LL | | };
175121
| |_____^
176122
|
177123
note: Capturing variant[] -> ImmBorrow
178-
--> $DIR/patterns-capture-analysis.rs:120:15
124+
--> $DIR/patterns-capture-analysis.rs:108:15
179125
|
180126
LL | match variant {
181127
| ^^^^^^^
182128

183129
error: Min Capture analysis includes:
184-
--> $DIR/patterns-capture-analysis.rs:117:5
130+
--> $DIR/patterns-capture-analysis.rs:105:5
185131
|
186132
LL | / || {
187133
LL | |
@@ -193,11 +139,130 @@ LL | | };
193139
| |_____^
194140
|
195141
note: Min Capture variant[] -> ImmBorrow
196-
--> $DIR/patterns-capture-analysis.rs:120:15
142+
--> $DIR/patterns-capture-analysis.rs:108:15
197143
|
198144
LL | match variant {
199145
| ^^^^^^^
200146

201-
error: aborting due to 15 previous errors
147+
error: First Pass analysis includes:
148+
--> $DIR/patterns-capture-analysis.rs:123:5
149+
|
150+
LL | / || {
151+
LL | |
152+
LL | |
153+
LL | | match slice {
154+
... |
155+
LL | | }
156+
LL | | };
157+
| |_____^
158+
|
159+
note: Capturing slice[] -> ImmBorrow
160+
--> $DIR/patterns-capture-analysis.rs:126:15
161+
|
162+
LL | match slice {
163+
| ^^^^^
164+
165+
error: Min Capture analysis includes:
166+
--> $DIR/patterns-capture-analysis.rs:123:5
167+
|
168+
LL | / || {
169+
LL | |
170+
LL | |
171+
LL | | match slice {
172+
... |
173+
LL | | }
174+
LL | | };
175+
| |_____^
176+
|
177+
note: Min Capture slice[] -> ImmBorrow
178+
--> $DIR/patterns-capture-analysis.rs:126:15
179+
|
180+
LL | match slice {
181+
| ^^^^^
182+
183+
error: First Pass analysis includes:
184+
--> $DIR/patterns-capture-analysis.rs:135:5
185+
|
186+
LL | / || {
187+
LL | |
188+
LL | |
189+
LL | | match slice {
190+
... |
191+
LL | | }
192+
LL | | };
193+
| |_____^
194+
|
195+
note: Capturing slice[] -> ImmBorrow
196+
--> $DIR/patterns-capture-analysis.rs:138:15
197+
|
198+
LL | match slice {
199+
| ^^^^^
200+
201+
error: Min Capture analysis includes:
202+
--> $DIR/patterns-capture-analysis.rs:135:5
203+
|
204+
LL | / || {
205+
LL | |
206+
LL | |
207+
LL | | match slice {
208+
... |
209+
LL | | }
210+
LL | | };
211+
| |_____^
212+
|
213+
note: Min Capture slice[] -> ImmBorrow
214+
--> $DIR/patterns-capture-analysis.rs:138:15
215+
|
216+
LL | match slice {
217+
| ^^^^^
218+
219+
error: First Pass analysis includes:
220+
--> $DIR/patterns-capture-analysis.rs:147:5
221+
|
222+
LL | / || {
223+
LL | |
224+
LL | |
225+
LL | | match slice {
226+
... |
227+
LL | | }
228+
LL | | };
229+
| |_____^
230+
|
231+
note: Capturing slice[] -> ImmBorrow
232+
--> $DIR/patterns-capture-analysis.rs:150:15
233+
|
234+
LL | match slice {
235+
| ^^^^^
236+
237+
error: Min Capture analysis includes:
238+
--> $DIR/patterns-capture-analysis.rs:147:5
239+
|
240+
LL | / || {
241+
LL | |
242+
LL | |
243+
LL | | match slice {
244+
... |
245+
LL | | }
246+
LL | | };
247+
| |_____^
248+
|
249+
note: Min Capture slice[] -> ImmBorrow
250+
--> $DIR/patterns-capture-analysis.rs:150:15
251+
|
252+
LL | match slice {
253+
| ^^^^^
254+
255+
error: First Pass analysis includes:
256+
--> $DIR/patterns-capture-analysis.rs:164:5
257+
|
258+
LL | / || {
259+
LL | |
260+
LL | | match slice {
261+
LL | | [..] => {},
262+
LL | | _ => {}
263+
LL | | }
264+
LL | | };
265+
| |_____^
266+
267+
error: aborting due to 16 previous errors
202268

203-
For more information about this error, try `rustc --explain E0658`.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
struct Header;
2+
struct EntryMetadata;
3+
struct Entry<A, B>(A, B);
4+
5+
trait Tr {
6+
type EncodedKey;
7+
type EncodedValue;
8+
}
9+
10+
fn test<C: Tr, R>(
11+
// This APIT is long, however we shouldn't render the type name with a newline in it.
12+
y: impl FnOnce(
13+
&mut Header,
14+
&mut [EntryMetadata],
15+
&mut [Entry<C::EncodedKey, C::EncodedValue>]
16+
) -> R,
17+
) {
18+
let () = y;
19+
//~^ ERROR mismatched types
20+
}
21+
22+
fn main() {}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/arg-position-impl-trait-too-long.rs:18:9
3+
|
4+
LL | y: impl FnOnce(
5+
| ________-
6+
LL | | &mut Header,
7+
LL | | &mut [EntryMetadata],
8+
LL | | &mut [Entry<C::EncodedKey, C::EncodedValue>]
9+
LL | | ) -> R,
10+
| |__________- this type parameter
11+
LL | ) {
12+
LL | let () = y;
13+
| ^^ - this expression has type `impl FnOnce(&mut Header, &mut [EntryMetadata], &mut [Entry<C::EncodedKey, C::EncodedValue>]) -> R`
14+
| |
15+
| expected type parameter `impl FnOnce(&mut Header, &mut [EntryMetadata], &mut [Entry<C::EncodedKey, C::EncodedValue>]) -> R`, found `()`
16+
|
17+
= note: expected type parameter `impl FnOnce(&mut Header, &mut [EntryMetadata], &mut [Entry<C::EncodedKey, C::EncodedValue>]) -> R`
18+
found unit type `()`
19+
20+
error: aborting due to previous error
21+
22+
For more information about this error, try `rustc --explain E0308`.

‎tests/ui/lint/lint-attr-everywhere-early.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,14 @@ fn expressions() {
134134
}
135135
}
136136

137+
match f {
138+
#[deny(ellipsis_inclusive_range_patterns)]
139+
Match{f1: 0...100} => {}
140+
//~^ ERROR range patterns are deprecated
141+
//~| WARNING this is accepted in the current edition
142+
_ => {}
143+
}
144+
137145
// Statement Block
138146
{
139147
#![deny(unsafe_code)]

‎tests/ui/lint/lint-attr-everywhere-early.stderr

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -384,103 +384,117 @@ note: the lint level is defined here
384384
LL | #[deny(while_true)]
385385
| ^^^^^^^^^^
386386

387+
error: `...` range patterns are deprecated
388+
--> $DIR/lint-attr-everywhere-early.rs:139:20
389+
|
390+
LL | Match{f1: 0...100} => {}
391+
| ^^^ help: use `..=` for an inclusive range
392+
|
393+
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
394+
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
395+
note: the lint level is defined here
396+
--> $DIR/lint-attr-everywhere-early.rs:138:16
397+
|
398+
LL | #[deny(ellipsis_inclusive_range_patterns)]
399+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
400+
387401
error: usage of an `unsafe` block
388-
--> $DIR/lint-attr-everywhere-early.rs:140:9
402+
--> $DIR/lint-attr-everywhere-early.rs:148:9
389403
|
390404
LL | unsafe {}
391405
| ^^^^^^^^^
392406
|
393407
note: the lint level is defined here
394-
--> $DIR/lint-attr-everywhere-early.rs:139:17
408+
--> $DIR/lint-attr-everywhere-early.rs:147:17
395409
|
396410
LL | #![deny(unsafe_code)]
397411
| ^^^^^^^^^^^
398412

399413
error: usage of an `unsafe` block
400-
--> $DIR/lint-attr-everywhere-early.rs:144:9
414+
--> $DIR/lint-attr-everywhere-early.rs:152:9
401415
|
402416
LL | unsafe {}
403417
| ^^^^^^^^^
404418
|
405419
note: the lint level is defined here
406-
--> $DIR/lint-attr-everywhere-early.rs:143:16
420+
--> $DIR/lint-attr-everywhere-early.rs:151:16
407421
|
408422
LL | #[deny(unsafe_code)]
409423
| ^^^^^^^^^^^
410424

411425
error: usage of an `unsafe` block
412-
--> $DIR/lint-attr-everywhere-early.rs:149:5
426+
--> $DIR/lint-attr-everywhere-early.rs:157:5
413427
|
414428
LL | unsafe {};
415429
| ^^^^^^^^^
416430
|
417431
note: the lint level is defined here
418-
--> $DIR/lint-attr-everywhere-early.rs:148:12
432+
--> $DIR/lint-attr-everywhere-early.rs:156:12
419433
|
420434
LL | #[deny(unsafe_code)]
421435
| ^^^^^^^^^^^
422436

423437
error: usage of an `unsafe` block
424-
--> $DIR/lint-attr-everywhere-early.rs:151:27
438+
--> $DIR/lint-attr-everywhere-early.rs:159:27
425439
|
426440
LL | [#[deny(unsafe_code)] unsafe {123}];
427441
| ^^^^^^^^^^^^
428442
|
429443
note: the lint level is defined here
430-
--> $DIR/lint-attr-everywhere-early.rs:151:13
444+
--> $DIR/lint-attr-everywhere-early.rs:159:13
431445
|
432446
LL | [#[deny(unsafe_code)] unsafe {123}];
433447
| ^^^^^^^^^^^
434448

435449
error: usage of an `unsafe` block
436-
--> $DIR/lint-attr-everywhere-early.rs:152:27
450+
--> $DIR/lint-attr-everywhere-early.rs:160:27
437451
|
438452
LL | (#[deny(unsafe_code)] unsafe {123},);
439453
| ^^^^^^^^^^^^
440454
|
441455
note: the lint level is defined here
442-
--> $DIR/lint-attr-everywhere-early.rs:152:13
456+
--> $DIR/lint-attr-everywhere-early.rs:160:13
443457
|
444458
LL | (#[deny(unsafe_code)] unsafe {123},);
445459
| ^^^^^^^^^^^
446460

447461
error: usage of an `unsafe` block
448-
--> $DIR/lint-attr-everywhere-early.rs:154:31
462+
--> $DIR/lint-attr-everywhere-early.rs:162:31
449463
|
450464
LL | call(#[deny(unsafe_code)] unsafe {123});
451465
| ^^^^^^^^^^^^
452466
|
453467
note: the lint level is defined here
454-
--> $DIR/lint-attr-everywhere-early.rs:154:17
468+
--> $DIR/lint-attr-everywhere-early.rs:162:17
455469
|
456470
LL | call(#[deny(unsafe_code)] unsafe {123});
457471
| ^^^^^^^^^^^
458472

459473
error: usage of an `unsafe` block
460-
--> $DIR/lint-attr-everywhere-early.rs:156:38
474+
--> $DIR/lint-attr-everywhere-early.rs:164:38
461475
|
462476
LL | TupleStruct(#[deny(unsafe_code)] unsafe {123});
463477
| ^^^^^^^^^^^^
464478
|
465479
note: the lint level is defined here
466-
--> $DIR/lint-attr-everywhere-early.rs:156:24
480+
--> $DIR/lint-attr-everywhere-early.rs:164:24
467481
|
468482
LL | TupleStruct(#[deny(unsafe_code)] unsafe {123});
469483
| ^^^^^^^^^^^
470484

471485
error: `...` range patterns are deprecated
472-
--> $DIR/lint-attr-everywhere-early.rs:167:18
486+
--> $DIR/lint-attr-everywhere-early.rs:175:18
473487
|
474488
LL | f1: 0...100,
475489
| ^^^ help: use `..=` for an inclusive range
476490
|
477491
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
478492
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
479493
note: the lint level is defined here
480-
--> $DIR/lint-attr-everywhere-early.rs:166:20
494+
--> $DIR/lint-attr-everywhere-early.rs:174:20
481495
|
482496
LL | #[deny(ellipsis_inclusive_range_patterns)]
483497
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
484498

485-
error: aborting due to 36 previous errors
499+
error: aborting due to 37 previous errors
486500

‎tests/ui/lint/lint-attr-everywhere-late.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,11 @@ fn expressions() {
162162
}
163163
}
164164

165+
match 123 {
166+
#[deny(non_snake_case)]
167+
ARM_VAR => {} //~ ERROR variable `ARM_VAR` should have a snake case name
168+
}
169+
165170
// Statement Block
166171
{
167172
#![deny(enum_intrinsics_non_enums)]

‎tests/ui/lint/lint-attr-everywhere-late.stderr

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -305,124 +305,136 @@ note: the lint level is defined here
305305
LL | #[deny(enum_intrinsics_non_enums)]
306306
| ^^^^^^^^^^^^^^^^^^^^^^^^^
307307

308+
error: variable `ARM_VAR` should have a snake case name
309+
--> $DIR/lint-attr-everywhere-late.rs:167:9
310+
|
311+
LL | ARM_VAR => {}
312+
| ^^^^^^^ help: convert the identifier to snake case: `arm_var`
313+
|
314+
note: the lint level is defined here
315+
--> $DIR/lint-attr-everywhere-late.rs:166:16
316+
|
317+
LL | #[deny(non_snake_case)]
318+
| ^^^^^^^^^^^^^^
319+
308320
error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
309-
--> $DIR/lint-attr-everywhere-late.rs:168:9
321+
--> $DIR/lint-attr-everywhere-late.rs:173:9
310322
|
311323
LL | discriminant::<i32>(&123);
312324
| ^^^^^^^^^^^^^^^^^^^^^^^^^
313325
|
314326
note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
315-
--> $DIR/lint-attr-everywhere-late.rs:168:29
327+
--> $DIR/lint-attr-everywhere-late.rs:173:29
316328
|
317329
LL | discriminant::<i32>(&123);
318330
| ^^^^
319331
note: the lint level is defined here
320-
--> $DIR/lint-attr-everywhere-late.rs:167:17
332+
--> $DIR/lint-attr-everywhere-late.rs:172:17
321333
|
322334
LL | #![deny(enum_intrinsics_non_enums)]
323335
| ^^^^^^^^^^^^^^^^^^^^^^^^^
324336

325337
error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
326-
--> $DIR/lint-attr-everywhere-late.rs:172:9
338+
--> $DIR/lint-attr-everywhere-late.rs:177:9
327339
|
328340
LL | discriminant::<i32>(&123);
329341
| ^^^^^^^^^^^^^^^^^^^^^^^^^
330342
|
331343
note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
332-
--> $DIR/lint-attr-everywhere-late.rs:172:29
344+
--> $DIR/lint-attr-everywhere-late.rs:177:29
333345
|
334346
LL | discriminant::<i32>(&123);
335347
| ^^^^
336348
note: the lint level is defined here
337-
--> $DIR/lint-attr-everywhere-late.rs:171:16
349+
--> $DIR/lint-attr-everywhere-late.rs:176:16
338350
|
339351
LL | #[deny(enum_intrinsics_non_enums)]
340352
| ^^^^^^^^^^^^^^^^^^^^^^^^^
341353

342354
error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
343-
--> $DIR/lint-attr-everywhere-late.rs:177:5
355+
--> $DIR/lint-attr-everywhere-late.rs:182:5
344356
|
345357
LL | discriminant::<i32>(&123);
346358
| ^^^^^^^^^^^^^^^^^^^^^^^^^
347359
|
348360
note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
349-
--> $DIR/lint-attr-everywhere-late.rs:177:25
361+
--> $DIR/lint-attr-everywhere-late.rs:182:25
350362
|
351363
LL | discriminant::<i32>(&123);
352364
| ^^^^
353365
note: the lint level is defined here
354-
--> $DIR/lint-attr-everywhere-late.rs:176:12
366+
--> $DIR/lint-attr-everywhere-late.rs:181:12
355367
|
356368
LL | #[deny(enum_intrinsics_non_enums)]
357369
| ^^^^^^^^^^^^^^^^^^^^^^^^^
358370

359371
error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
360-
--> $DIR/lint-attr-everywhere-late.rs:179:41
372+
--> $DIR/lint-attr-everywhere-late.rs:184:41
361373
|
362374
LL | [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
363375
| ^^^^^^^^^^^^^^^^^^^^^^^^^
364376
|
365377
note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
366-
--> $DIR/lint-attr-everywhere-late.rs:179:61
378+
--> $DIR/lint-attr-everywhere-late.rs:184:61
367379
|
368380
LL | [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
369381
| ^^^^
370382
note: the lint level is defined here
371-
--> $DIR/lint-attr-everywhere-late.rs:179:13
383+
--> $DIR/lint-attr-everywhere-late.rs:184:13
372384
|
373385
LL | [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
374386
| ^^^^^^^^^^^^^^^^^^^^^^^^^
375387

376388
error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
377-
--> $DIR/lint-attr-everywhere-late.rs:180:41
389+
--> $DIR/lint-attr-everywhere-late.rs:185:41
378390
|
379391
LL | (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
380392
| ^^^^^^^^^^^^^^^^^^^^^^^^^
381393
|
382394
note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
383-
--> $DIR/lint-attr-everywhere-late.rs:180:61
395+
--> $DIR/lint-attr-everywhere-late.rs:185:61
384396
|
385397
LL | (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
386398
| ^^^^
387399
note: the lint level is defined here
388-
--> $DIR/lint-attr-everywhere-late.rs:180:13
400+
--> $DIR/lint-attr-everywhere-late.rs:185:13
389401
|
390402
LL | (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
391403
| ^^^^^^^^^^^^^^^^^^^^^^^^^
392404

393405
error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
394-
--> $DIR/lint-attr-everywhere-late.rs:182:45
406+
--> $DIR/lint-attr-everywhere-late.rs:187:45
395407
|
396408
LL | call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
397409
| ^^^^^^^^^^^^^^^^^^^^^^^^^
398410
|
399411
note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
400-
--> $DIR/lint-attr-everywhere-late.rs:182:65
412+
--> $DIR/lint-attr-everywhere-late.rs:187:65
401413
|
402414
LL | call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
403415
| ^^^^
404416
note: the lint level is defined here
405-
--> $DIR/lint-attr-everywhere-late.rs:182:17
417+
--> $DIR/lint-attr-everywhere-late.rs:187:17
406418
|
407419
LL | call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
408420
| ^^^^^^^^^^^^^^^^^^^^^^^^^
409421

410422
error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
411-
--> $DIR/lint-attr-everywhere-late.rs:184:52
423+
--> $DIR/lint-attr-everywhere-late.rs:189:52
412424
|
413425
LL | TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
414426
| ^^^^^^^^^^^^^^^^^^^^^^^^^
415427
|
416428
note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
417-
--> $DIR/lint-attr-everywhere-late.rs:184:72
429+
--> $DIR/lint-attr-everywhere-late.rs:189:72
418430
|
419431
LL | TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
420432
| ^^^^
421433
note: the lint level is defined here
422-
--> $DIR/lint-attr-everywhere-late.rs:184:24
434+
--> $DIR/lint-attr-everywhere-late.rs:189:24
423435
|
424436
LL | TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
425437
| ^^^^^^^^^^^^^^^^^^^^^^^^^
426438

427-
error: aborting due to 31 previous errors
439+
error: aborting due to 32 previous errors
428440

‎tests/ui/lint/lint-match-arms-2.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#![feature(if_let_guard)]
2+
#![allow(unused, non_snake_case)]
3+
4+
enum E {
5+
A,
6+
}
7+
8+
#[allow(bindings_with_variant_name, irrefutable_let_patterns)]
9+
fn foo() {
10+
match E::A {
11+
#[deny(bindings_with_variant_name)]
12+
A => {}
13+
//~^ ERROR pattern binding `A` is named the same as one of the variants of the type `E`
14+
}
15+
16+
match &E::A {
17+
#[deny(irrefutable_let_patterns)]
18+
a if let b = a => {}
19+
//~^ ERROR irrefutable `if let` guard pattern
20+
_ => {}
21+
}
22+
}
23+
24+
fn main() { }
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0170]: pattern binding `A` is named the same as one of the variants of the type `E`
2+
--> $DIR/lint-match-arms-2.rs:12:9
3+
|
4+
LL | A => {}
5+
| ^ help: to match on the variant, qualify the path: `E::A`
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/lint-match-arms-2.rs:11:16
9+
|
10+
LL | #[deny(bindings_with_variant_name)]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: irrefutable `if let` guard pattern
14+
--> $DIR/lint-match-arms-2.rs:18:18
15+
|
16+
LL | a if let b = a => {}
17+
| ^
18+
|
19+
= note: this pattern will always match, so the guard is useless
20+
= help: consider removing the guard and adding a `let` inside the match arm
21+
note: the lint level is defined here
22+
--> $DIR/lint-match-arms-2.rs:17:16
23+
|
24+
LL | #[deny(irrefutable_let_patterns)]
25+
| ^^^^^^^^^^^^^^^^^^^^^^^^
26+
27+
error: aborting due to 2 previous errors
28+
29+
For more information about this error, try `rustc --explain E0170`.

0 commit comments

Comments
 (0)
Please sign in to comment.