Skip to content

Commit 99b8953

Browse files
committed
Auto merge of rust-lang#67356 - Centril:rollup-paaw3ju, r=Centril
Rollup of 8 pull requests Successful merges: - rust-lang#67249 (Improve code generated for `starts_with(<literal char>)`) - rust-lang#67308 (Delete flaky test net::tcp::tests::fast_rebind) - rust-lang#67318 (Improve typeck & lowering docs for slice patterns) - rust-lang#67322 (use Self alias in place of macros) - rust-lang#67323 (make transparent enums more ordinary) - rust-lang#67336 (Fix JS error when loading page with search) - rust-lang#67344 (.gitignore: Don't ignore a file that exists in the repository) - rust-lang#67349 (Minor: update Unsize docs for dyn syntax) Failed merges: r? @ghost
2 parents f0d4b57 + 733559b commit 99b8953

File tree

13 files changed

+134
-70
lines changed

13 files changed

+134
-70
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,6 @@ config.mk
5555
config.stamp
5656
Session.vim
5757
.cargo
58+
!/src/test/run-make/thumb-none-qemu/example/.cargo
5859
no_llvm_build
5960
# Before adding new lines, see the comment at the top.

src/libcore/benches/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ mod hash;
1111
mod iter;
1212
mod num;
1313
mod ops;
14+
mod pattern;
1415
mod slice;

src/libcore/benches/pattern.rs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
use test::black_box;
2+
use test::Bencher;
3+
4+
#[bench]
5+
fn starts_with_char(b: &mut Bencher) {
6+
let text = black_box("kdjsfhlakfhlsghlkvcnljknfqiunvcijqenwodind");
7+
b.iter(|| {
8+
for _ in 0..1024 {
9+
black_box(text.starts_with('k'));
10+
}
11+
})
12+
}
13+
14+
#[bench]
15+
fn starts_with_str(b: &mut Bencher) {
16+
let text = black_box("kdjsfhlakfhlsghlkvcnljknfqiunvcijqenwodind");
17+
b.iter(|| {
18+
for _ in 0..1024 {
19+
black_box(text.starts_with("k"));
20+
}
21+
})
22+
}
23+
24+
25+
#[bench]
26+
fn ends_with_char(b: &mut Bencher) {
27+
let text = black_box("kdjsfhlakfhlsghlkvcnljknfqiunvcijqenwodind");
28+
b.iter(|| {
29+
for _ in 0..1024 {
30+
black_box(text.ends_with('k'));
31+
}
32+
})
33+
}
34+
35+
#[bench]
36+
fn ends_with_str(b: &mut Bencher) {
37+
let text = black_box("kdjsfhlakfhlsghlkvcnljknfqiunvcijqenwodind");
38+
b.iter(|| {
39+
for _ in 0..1024 {
40+
black_box(text.ends_with("k"));
41+
}
42+
})
43+
}

src/libcore/marker.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ pub trait Sized {
9797
/// Types that can be "unsized" to a dynamically-sized type.
9898
///
9999
/// For example, the sized array type `[i8; 2]` implements `Unsize<[i8]>` and
100-
/// `Unsize<fmt::Debug>`.
100+
/// `Unsize<dyn fmt::Debug>`.
101101
///
102102
/// All implementations of `Unsize` are provided automatically by the compiler.
103103
///

src/libcore/num/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", s
6767
)]
6868
#[inline]
6969
pub const unsafe fn new_unchecked(n: $Int) -> Self {
70-
$Ty(n)
70+
Self(n)
7171
}
7272

7373
/// Creates a non-zero if the given value is not zero.
@@ -76,7 +76,7 @@ assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", s
7676
pub fn new(n: $Int) -> Option<Self> {
7777
if n != 0 {
7878
// SAFETY: we just checked that there's no `0`
79-
Some(unsafe { $Ty(n) })
79+
Some(unsafe { Self(n) })
8080
} else {
8181
None
8282
}

src/libcore/str/pattern.rs

+4-15
Original file line numberDiff line numberDiff line change
@@ -445,21 +445,13 @@ impl<'a> Pattern<'a> for char {
445445

446446
#[inline]
447447
fn is_prefix_of(self, haystack: &'a str) -> bool {
448-
if let Some(ch) = haystack.chars().next() {
449-
self == ch
450-
} else {
451-
false
452-
}
448+
self.encode_utf8(&mut [0u8; 4]).is_prefix_of(haystack)
453449
}
454450

455451
#[inline]
456452
fn is_suffix_of(self, haystack: &'a str) -> bool where Self::Searcher: ReverseSearcher<'a>
457453
{
458-
if let Some(ch) = haystack.chars().next_back() {
459-
self == ch
460-
} else {
461-
false
462-
}
454+
self.encode_utf8(&mut [0u8; 4]).is_suffix_of(haystack)
463455
}
464456
}
465457

@@ -710,16 +702,13 @@ impl<'a, 'b> Pattern<'a> for &'b str {
710702
/// Checks whether the pattern matches at the front of the haystack
711703
#[inline]
712704
fn is_prefix_of(self, haystack: &'a str) -> bool {
713-
haystack.is_char_boundary(self.len()) &&
714-
self == &haystack[..self.len()]
705+
haystack.as_bytes().starts_with(self.as_bytes())
715706
}
716707

717708
/// Checks whether the pattern matches at the back of the haystack
718709
#[inline]
719710
fn is_suffix_of(self, haystack: &'a str) -> bool {
720-
self.len() <= haystack.len() &&
721-
haystack.is_char_boundary(haystack.len() - self.len()) &&
722-
self == &haystack[haystack.len() - self.len()..]
711+
haystack.as_bytes().ends_with(self.as_bytes())
723712
}
724713
}
725714

src/libcore/sync/atomic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1263,7 +1263,7 @@ let atomic_forty_two = ", stringify!($atomic_type), "::new(42);
12631263
#[$stable]
12641264
#[cfg_attr(not(bootstrap), $const_stable)]
12651265
pub const fn new(v: $int_type) -> Self {
1266-
$atomic_type {v: UnsafeCell::new(v)}
1266+
Self {v: UnsafeCell::new(v)}
12671267
}
12681268
}
12691269

src/librustc/hir/lowering.rs

+26-12
Original file line numberDiff line numberDiff line change
@@ -2852,19 +2852,23 @@ impl<'a> LoweringContext<'a> {
28522852
let mut rest = None;
28532853

28542854
let mut iter = pats.iter().enumerate();
2855-
while let Some((idx, pat)) = iter.next() {
2856-
// Interpret the first `..` pattern as a subtuple pattern.
2855+
for (idx, pat) in iter.by_ref() {
2856+
// Interpret the first `..` pattern as a sub-tuple pattern.
2857+
// Note that unlike for slice patterns,
2858+
// where `xs @ ..` is a legal sub-slice pattern,
2859+
// it is not a legal sub-tuple pattern.
28572860
if pat.is_rest() {
28582861
rest = Some((idx, pat.span));
28592862
break;
28602863
}
2861-
// It was not a subslice pattern so lower it normally.
2864+
// It was not a sub-tuple pattern so lower it normally.
28622865
elems.push(self.lower_pat(pat));
28632866
}
28642867

2865-
while let Some((_, pat)) = iter.next() {
2866-
// There was a previous subtuple pattern; make sure we don't allow more.
2868+
for (_, pat) in iter {
2869+
// There was a previous sub-tuple pattern; make sure we don't allow more...
28672870
if pat.is_rest() {
2871+
// ...but there was one again, so error.
28682872
self.ban_extra_rest_pat(pat.span, rest.unwrap().1, ctx);
28692873
} else {
28702874
elems.push(self.lower_pat(pat));
@@ -2874,36 +2878,44 @@ impl<'a> LoweringContext<'a> {
28742878
(elems.into(), rest.map(|(ddpos, _)| ddpos))
28752879
}
28762880

2881+
/// Lower a slice pattern of form `[pat_0, ..., pat_n]` into
2882+
/// `hir::PatKind::Slice(before, slice, after)`.
2883+
///
2884+
/// When encountering `($binding_mode $ident @)? ..` (`slice`),
2885+
/// this is interpreted as a sub-slice pattern semantically.
2886+
/// Patterns that follow, which are not like `slice` -- or an error occurs, are in `after`.
28772887
fn lower_pat_slice(&mut self, pats: &[AstP<Pat>]) -> hir::PatKind {
28782888
let mut before = Vec::new();
28792889
let mut after = Vec::new();
28802890
let mut slice = None;
28812891
let mut prev_rest_span = None;
28822892

28832893
let mut iter = pats.iter();
2884-
while let Some(pat) = iter.next() {
2885-
// Interpret the first `((ref mut?)? x @)? ..` pattern as a subslice pattern.
2894+
// Lower all the patterns until the first occurence of a sub-slice pattern.
2895+
for pat in iter.by_ref() {
28862896
match pat.kind {
2897+
// Found a sub-slice pattern `..`. Record, lower it to `_`, and stop here.
28872898
PatKind::Rest => {
28882899
prev_rest_span = Some(pat.span);
28892900
slice = Some(self.pat_wild_with_node_id_of(pat));
28902901
break;
28912902
},
2903+
// Found a sub-slice pattern `$binding_mode $ident @ ..`.
2904+
// Record, lower it to `$binding_mode $ident @ _`, and stop here.
28922905
PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => {
28932906
prev_rest_span = Some(sub.span);
28942907
let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub));
28952908
let node = self.lower_pat_ident(pat, bm, ident, lower_sub);
28962909
slice = Some(self.pat_with_node_id_of(pat, node));
28972910
break;
28982911
},
2899-
_ => {}
2912+
// It was not a subslice pattern so lower it normally.
2913+
_ => before.push(self.lower_pat(pat)),
29002914
}
2901-
2902-
// It was not a subslice pattern so lower it normally.
2903-
before.push(self.lower_pat(pat));
29042915
}
29052916

2906-
while let Some(pat) = iter.next() {
2917+
// Lower all the patterns after the first sub-slice pattern.
2918+
for pat in iter {
29072919
// There was a previous subslice pattern; make sure we don't allow more.
29082920
let rest_span = match pat.kind {
29092921
PatKind::Rest => Some(pat.span),
@@ -2915,8 +2927,10 @@ impl<'a> LoweringContext<'a> {
29152927
_ => None,
29162928
};
29172929
if let Some(rest_span) = rest_span {
2930+
// We have e.g., `[a, .., b, ..]`. That's no good, error!
29182931
self.ban_extra_rest_pat(rest_span, prev_rest_span.unwrap(), "slice");
29192932
} else {
2933+
// Lower the pattern normally.
29202934
after.push(self.lower_pat(pat));
29212935
}
29222936
}

src/librustc/hir/mod.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -1048,8 +1048,15 @@ pub enum PatKind {
10481048
/// A range pattern (e.g., `1..=2` or `1..2`).
10491049
Range(P<Expr>, P<Expr>, RangeEnd),
10501050

1051-
/// `[a, b, ..i, y, z]` is represented as:
1052-
/// `PatKind::Slice(box [a, b], Some(i), box [y, z])`.
1051+
/// A slice pattern, `[before_0, ..., before_n, (slice, after_0, ..., after_n)?]`.
1052+
///
1053+
/// Here, `slice` is lowered from the syntax `($binding_mode $ident @)? ..`.
1054+
/// If `slice` exists, then `after` can be non-empty.
1055+
///
1056+
/// The representation for e.g., `[a, b, .., c, d]` is:
1057+
/// ```
1058+
/// PatKind::Slice([Binding(a), Binding(b)], Some(Wild), [Binding(c), Binding(d)])
1059+
/// ```
10531060
Slice(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>),
10541061
}
10551062

src/librustc_typeck/check/mod.rs

+20-21
Original file line numberDiff line numberDiff line change
@@ -2330,7 +2330,7 @@ fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, d
23302330
);
23312331
let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
23322332
err.span_label(sp, &msg);
2333-
if let &[ref start @ .., ref end] = &variant_spans[..] {
2333+
if let [start @ .., end] = &*variant_spans {
23342334
for variant_span in start {
23352335
err.span_label(*variant_span, "");
23362336
}
@@ -2372,23 +2372,14 @@ fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
23722372
}
23732373
let sp = tcx.sess.source_map().def_span(sp);
23742374

2375-
if adt.is_enum() {
2376-
if !tcx.features().transparent_enums {
2377-
feature_err(
2378-
&tcx.sess.parse_sess,
2379-
sym::transparent_enums,
2380-
sp,
2381-
"transparent enums are unstable",
2382-
)
2383-
.emit();
2384-
}
2385-
if adt.variants.len() != 1 {
2386-
bad_variant_count(tcx, adt, sp, def_id);
2387-
if adt.variants.is_empty() {
2388-
// Don't bother checking the fields. No variants (and thus no fields) exist.
2389-
return;
2390-
}
2391-
}
2375+
if adt.is_enum() && !tcx.features().transparent_enums {
2376+
feature_err(
2377+
&tcx.sess.parse_sess,
2378+
sym::transparent_enums,
2379+
sp,
2380+
"transparent enums are unstable",
2381+
)
2382+
.emit();
23922383
}
23932384

23942385
if adt.is_union() && !tcx.features().transparent_unions {
@@ -2401,6 +2392,14 @@ fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
24012392
.emit();
24022393
}
24032394

2395+
if adt.variants.len() != 1 {
2396+
bad_variant_count(tcx, adt, sp, def_id);
2397+
if adt.variants.is_empty() {
2398+
// Don't bother checking the fields. No variants (and thus no fields) exist.
2399+
return;
2400+
}
2401+
}
2402+
24042403
// For each field, figure out if it's known to be a ZST and align(1)
24052404
let field_infos = adt.all_fields().map(|field| {
24062405
let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
@@ -5351,9 +5350,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
53515350
directly, not through a function pointer");
53525351
}
53535352

5354-
// Resolves `typ` by a single level if `typ` is a type variable.
5355-
// If no resolution is possible, then an error is reported.
5356-
// Numeric inference variables may be left unresolved.
5353+
/// Resolves `typ` by a single level if `typ` is a type variable.
5354+
/// If no resolution is possible, then an error is reported.
5355+
/// Numeric inference variables may be left unresolved.
53575356
pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
53585357
let ty = self.resolve_vars_with_obligations(ty);
53595358
if !ty.is_ty_var() {

src/librustc_typeck/check/pat.rs

+25
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11541154
self.tcx.mk_ref(region, mt)
11551155
}
11561156

1157+
/// Type check a slice pattern.
1158+
///
1159+
/// Syntactically, these look like `[pat_0, ..., pat_n]`.
1160+
/// Semantically, we are type checking a pattern with structure:
1161+
/// ```
1162+
/// [before_0, ..., before_n, (slice, after_0, ... after_n)?]
1163+
/// ```
1164+
/// The type of `slice`, if it is present, depends on the `expected` type.
1165+
/// If `slice` is missing, then so is `after_i`.
1166+
/// If `slice` is present, it can still represent 0 elements.
11571167
fn check_pat_slice(
11581168
&self,
11591169
span: Span,
@@ -1167,27 +1177,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11671177
let tcx = self.tcx;
11681178
let expected_ty = self.structurally_resolved_type(span, expected);
11691179
let (inner_ty, slice_ty) = match expected_ty.kind {
1180+
// An array, so we might have something like `let [a, b, c] = [0, 1, 2];`.
11701181
ty::Array(inner_ty, size) => {
11711182
let slice_ty = if let Some(size) = size.try_eval_usize(tcx, self.param_env) {
1183+
// Now we know the length...
11721184
let min_len = before.len() as u64 + after.len() as u64;
11731185
if slice.is_none() {
1186+
// ...and since there is no variable-length pattern,
1187+
// we require an exact match between the number of elements
1188+
// in the array pattern and as provided by the matched type.
11741189
if min_len != size {
11751190
self.error_scrutinee_inconsistent_length(span, min_len, size)
11761191
}
11771192
tcx.types.err
11781193
} else if let Some(rest) = size.checked_sub(min_len) {
1194+
// The variable-length pattern was there,
1195+
// so it has an array type with the remaining elements left as its size...
11791196
tcx.mk_array(inner_ty, rest)
11801197
} else {
1198+
// ...however, in this case, there were no remaining elements.
1199+
// That is, the slice pattern requires more than the array type offers.
11811200
self.error_scrutinee_with_rest_inconsistent_length(span, min_len, size);
11821201
tcx.types.err
11831202
}
11841203
} else {
1204+
// No idea what the length is, which happens if we have e.g.,
1205+
// `let [a, b] = arr` where `arr: [T; N]` where `const N: usize`.
11851206
self.error_scrutinee_unfixed_length(span);
11861207
tcx.types.err
11871208
};
11881209
(inner_ty, slice_ty)
11891210
}
11901211
ty::Slice(inner_ty) => (inner_ty, expected_ty),
1212+
// The expected type must be an array or slice, but was neither, so error.
11911213
_ => {
11921214
if !expected_ty.references_error() {
11931215
self.error_expected_array_or_slice(span, expected_ty);
@@ -1196,12 +1218,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11961218
}
11971219
};
11981220

1221+
// Type check all the patterns before `slice`.
11991222
for elt in before {
12001223
self.check_pat(&elt, inner_ty, def_bm, discrim_span);
12011224
}
1225+
// Type check the `slice`, if present, against its expected type.
12021226
if let Some(slice) = slice {
12031227
self.check_pat(&slice, slice_ty, def_bm, discrim_span);
12041228
}
1229+
// Type check the elements after `slice`, if present.
12051230
for elt in after {
12061231
self.check_pat(&elt, inner_ty, def_bm, discrim_span);
12071232
}

src/librustdoc/html/static/main.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2683,7 +2683,7 @@ function getSearchElement() {
26832683
insertAfter(popup, getSearchElement());
26842684
}
26852685

2686-
onHashChange();
2686+
onHashChange(null);
26872687
window.onhashchange = onHashChange;
26882688

26892689
buildHelperPopup();

0 commit comments

Comments
 (0)