about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-12-16 18:55:07 +0000
committerbors <bors@rust-lang.org>2019-12-16 18:55:07 +0000
commit99b89533d4cdf7682ea4054ad0ee36c351d05df1 (patch)
tree82ce6096679ca921b3eb76f24cf8480ecfc77802 /src
parentf0d4b571936d4072ed90ab7750636f68f1443b3e (diff)
parent733559b0c292cfa3fd6e4afffd820fa903ea320a (diff)
downloadrust-99b89533d4cdf7682ea4054ad0ee36c351d05df1.tar.gz
rust-99b89533d4cdf7682ea4054ad0ee36c351d05df1.zip
Auto merge of #67356 - Centril:rollup-paaw3ju, r=Centril
Rollup of 8 pull requests

Successful merges:

 - #67249 (Improve code generated for `starts_with(<literal char>)`)
 - #67308 (Delete flaky test net::tcp::tests::fast_rebind)
 - #67318 (Improve typeck & lowering docs for slice patterns)
 - #67322 (use Self alias in place of macros)
 - #67323 (make transparent enums more ordinary)
 - #67336 (Fix JS error when loading page with search)
 - #67344 (.gitignore: Don't ignore a file that exists in the repository)
 - #67349 (Minor: update Unsize docs for dyn syntax)

Failed merges:

r? @ghost
Diffstat (limited to 'src')
-rw-r--r--src/libcore/benches/lib.rs1
-rw-r--r--src/libcore/benches/pattern.rs43
-rw-r--r--src/libcore/marker.rs2
-rw-r--r--src/libcore/num/mod.rs4
-rw-r--r--src/libcore/str/pattern.rs19
-rw-r--r--src/libcore/sync/atomic.rs2
-rw-r--r--src/librustc/hir/lowering.rs38
-rw-r--r--src/librustc/hir/mod.rs11
-rw-r--r--src/librustc_typeck/check/mod.rs41
-rw-r--r--src/librustc_typeck/check/pat.rs25
-rw-r--r--src/librustdoc/html/static/main.js2
-rw-r--r--src/libstd/net/tcp.rs15
12 files changed, 133 insertions, 70 deletions
diff --git a/src/libcore/benches/lib.rs b/src/libcore/benches/lib.rs
index 6932c7fe221..570fc4ab933 100644
--- a/src/libcore/benches/lib.rs
+++ b/src/libcore/benches/lib.rs
@@ -11,4 +11,5 @@ mod hash;
 mod iter;
 mod num;
 mod ops;
+mod pattern;
 mod slice;
diff --git a/src/libcore/benches/pattern.rs b/src/libcore/benches/pattern.rs
new file mode 100644
index 00000000000..a49490cec12
--- /dev/null
+++ b/src/libcore/benches/pattern.rs
@@ -0,0 +1,43 @@
+use test::black_box;
+use test::Bencher;
+
+#[bench]
+fn starts_with_char(b: &mut Bencher) {
+    let text = black_box("kdjsfhlakfhlsghlkvcnljknfqiunvcijqenwodind");
+    b.iter(|| {
+        for _ in 0..1024 {
+            black_box(text.starts_with('k'));
+        }
+    })
+}
+
+#[bench]
+fn starts_with_str(b: &mut Bencher) {
+    let text = black_box("kdjsfhlakfhlsghlkvcnljknfqiunvcijqenwodind");
+    b.iter(|| {
+        for _ in 0..1024 {
+            black_box(text.starts_with("k"));
+        }
+    })
+}
+
+
+#[bench]
+fn ends_with_char(b: &mut Bencher) {
+    let text = black_box("kdjsfhlakfhlsghlkvcnljknfqiunvcijqenwodind");
+    b.iter(|| {
+        for _ in 0..1024 {
+            black_box(text.ends_with('k'));
+        }
+    })
+}
+
+#[bench]
+fn ends_with_str(b: &mut Bencher) {
+    let text = black_box("kdjsfhlakfhlsghlkvcnljknfqiunvcijqenwodind");
+    b.iter(|| {
+        for _ in 0..1024 {
+            black_box(text.ends_with("k"));
+        }
+    })
+}
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 2db55508ad5..1b586c3e5fe 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -97,7 +97,7 @@ pub trait Sized {
 /// Types that can be "unsized" to a dynamically-sized type.
 ///
 /// For example, the sized array type `[i8; 2]` implements `Unsize<[i8]>` and
-/// `Unsize<fmt::Debug>`.
+/// `Unsize<dyn fmt::Debug>`.
 ///
 /// All implementations of `Unsize` are provided automatically by the compiler.
 ///
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 33715418ffd..d091a8d86ea 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -67,7 +67,7 @@ assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", s
                 )]
                 #[inline]
                 pub const unsafe fn new_unchecked(n: $Int) -> Self {
-                    $Ty(n)
+                    Self(n)
                 }
 
                 /// 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
                 pub fn new(n: $Int) -> Option<Self> {
                     if n != 0 {
                         // SAFETY: we just checked that there's no `0`
-                        Some(unsafe { $Ty(n) })
+                        Some(unsafe { Self(n) })
                     } else {
                         None
                     }
diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs
index 1037da14b5f..b7ebd5f88b5 100644
--- a/src/libcore/str/pattern.rs
+++ b/src/libcore/str/pattern.rs
@@ -445,21 +445,13 @@ impl<'a> Pattern<'a> for char {
 
     #[inline]
     fn is_prefix_of(self, haystack: &'a str) -> bool {
-        if let Some(ch) = haystack.chars().next() {
-            self == ch
-        } else {
-            false
-        }
+        self.encode_utf8(&mut [0u8; 4]).is_prefix_of(haystack)
     }
 
     #[inline]
     fn is_suffix_of(self, haystack: &'a str) -> bool where Self::Searcher: ReverseSearcher<'a>
     {
-        if let Some(ch) = haystack.chars().next_back() {
-            self == ch
-        } else {
-            false
-        }
+        self.encode_utf8(&mut [0u8; 4]).is_suffix_of(haystack)
     }
 }
 
@@ -710,16 +702,13 @@ impl<'a, 'b> Pattern<'a> for &'b str {
     /// Checks whether the pattern matches at the front of the haystack
     #[inline]
     fn is_prefix_of(self, haystack: &'a str) -> bool {
-        haystack.is_char_boundary(self.len()) &&
-            self == &haystack[..self.len()]
+        haystack.as_bytes().starts_with(self.as_bytes())
     }
 
     /// Checks whether the pattern matches at the back of the haystack
     #[inline]
     fn is_suffix_of(self, haystack: &'a str) -> bool {
-        self.len() <= haystack.len() &&
-            haystack.is_char_boundary(haystack.len() - self.len()) &&
-            self == &haystack[haystack.len() - self.len()..]
+        haystack.as_bytes().ends_with(self.as_bytes())
     }
 }
 
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 7756335ee20..d5b0bc42038 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -1263,7 +1263,7 @@ let atomic_forty_two = ", stringify!($atomic_type), "::new(42);
                 #[$stable]
                 #[cfg_attr(not(bootstrap), $const_stable)]
                 pub const fn new(v: $int_type) -> Self {
-                    $atomic_type {v: UnsafeCell::new(v)}
+                    Self {v: UnsafeCell::new(v)}
                 }
             }
 
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index e13f6cabb52..ec9d6802def 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -2852,19 +2852,23 @@ impl<'a> LoweringContext<'a> {
         let mut rest = None;
 
         let mut iter = pats.iter().enumerate();
-        while let Some((idx, pat)) = iter.next() {
-            // Interpret the first `..` pattern as a subtuple pattern.
+        for (idx, pat) in iter.by_ref() {
+            // Interpret the first `..` pattern as a sub-tuple pattern.
+            // Note that unlike for slice patterns,
+            // where `xs @ ..` is a legal sub-slice pattern,
+            // it is not a legal sub-tuple pattern.
             if pat.is_rest() {
                 rest = Some((idx, pat.span));
                 break;
             }
-            // It was not a subslice pattern so lower it normally.
+            // It was not a sub-tuple pattern so lower it normally.
             elems.push(self.lower_pat(pat));
         }
 
-        while let Some((_, pat)) = iter.next() {
-            // There was a previous subtuple pattern; make sure we don't allow more.
+        for (_, pat) in iter {
+            // There was a previous sub-tuple pattern; make sure we don't allow more...
             if pat.is_rest() {
+                // ...but there was one again, so error.
                 self.ban_extra_rest_pat(pat.span, rest.unwrap().1, ctx);
             } else {
                 elems.push(self.lower_pat(pat));
@@ -2874,6 +2878,12 @@ impl<'a> LoweringContext<'a> {
         (elems.into(), rest.map(|(ddpos, _)| ddpos))
     }
 
+    /// Lower a slice pattern of form `[pat_0, ..., pat_n]` into
+    /// `hir::PatKind::Slice(before, slice, after)`.
+    ///
+    /// When encountering `($binding_mode $ident @)? ..` (`slice`),
+    /// this is interpreted as a sub-slice pattern semantically.
+    /// Patterns that follow, which are not like `slice` -- or an error occurs, are in `after`.
     fn lower_pat_slice(&mut self, pats: &[AstP<Pat>]) -> hir::PatKind {
         let mut before = Vec::new();
         let mut after = Vec::new();
@@ -2881,14 +2891,17 @@ impl<'a> LoweringContext<'a> {
         let mut prev_rest_span = None;
 
         let mut iter = pats.iter();
-        while let Some(pat) = iter.next() {
-            // Interpret the first `((ref mut?)? x @)? ..` pattern as a subslice pattern.
+        // Lower all the patterns until the first occurence of a sub-slice pattern.
+        for pat in iter.by_ref() {
             match pat.kind {
+                // Found a sub-slice pattern `..`. Record, lower it to `_`, and stop here.
                 PatKind::Rest => {
                     prev_rest_span = Some(pat.span);
                     slice = Some(self.pat_wild_with_node_id_of(pat));
                     break;
                 },
+                // Found a sub-slice pattern `$binding_mode $ident @ ..`.
+                // Record, lower it to `$binding_mode $ident @ _`, and stop here.
                 PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => {
                     prev_rest_span = Some(sub.span);
                     let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub));
@@ -2896,14 +2909,13 @@ impl<'a> LoweringContext<'a> {
                     slice = Some(self.pat_with_node_id_of(pat, node));
                     break;
                 },
-                _ => {}
+                // It was not a subslice pattern so lower it normally.
+                _ => before.push(self.lower_pat(pat)),
             }
-
-            // It was not a subslice pattern so lower it normally.
-            before.push(self.lower_pat(pat));
         }
 
-        while let Some(pat) = iter.next() {
+        // Lower all the patterns after the first sub-slice pattern.
+        for pat in iter {
             // There was a previous subslice pattern; make sure we don't allow more.
             let rest_span = match pat.kind {
                 PatKind::Rest => Some(pat.span),
@@ -2915,8 +2927,10 @@ impl<'a> LoweringContext<'a> {
                 _ => None,
             };
             if let Some(rest_span) = rest_span {
+                // We have e.g., `[a, .., b, ..]`. That's no good, error!
                 self.ban_extra_rest_pat(rest_span, prev_rest_span.unwrap(), "slice");
             } else {
+                // Lower the pattern normally.
                 after.push(self.lower_pat(pat));
             }
         }
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 66bb3a8d883..6b354b01518 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -1048,8 +1048,15 @@ pub enum PatKind {
     /// A range pattern (e.g., `1..=2` or `1..2`).
     Range(P<Expr>, P<Expr>, RangeEnd),
 
-    /// `[a, b, ..i, y, z]` is represented as:
-    ///     `PatKind::Slice(box [a, b], Some(i), box [y, z])`.
+    /// A slice pattern, `[before_0, ..., before_n, (slice, after_0, ..., after_n)?]`.
+    ///
+    /// Here, `slice` is lowered from the syntax `($binding_mode $ident @)? ..`.
+    /// If `slice` exists, then `after` can be non-empty.
+    ///
+    /// The representation for e.g., `[a, b, .., c, d]` is:
+    /// ```
+    /// PatKind::Slice([Binding(a), Binding(b)], Some(Wild), [Binding(c), Binding(d)])
+    /// ```
     Slice(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>),
 }
 
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 43e7bbcf0c0..09771bb7625 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2330,7 +2330,7 @@ fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, d
     );
     let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
     err.span_label(sp, &msg);
-    if let &[ref start @ .., ref end] = &variant_spans[..] {
+    if let [start @ .., end] = &*variant_spans {
         for variant_span in start {
             err.span_label(*variant_span, "");
         }
@@ -2372,23 +2372,14 @@ fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
     }
     let sp = tcx.sess.source_map().def_span(sp);
 
-    if adt.is_enum() {
-        if !tcx.features().transparent_enums {
-            feature_err(
-                &tcx.sess.parse_sess,
-                sym::transparent_enums,
-                sp,
-                "transparent enums are unstable",
-            )
-            .emit();
-        }
-        if adt.variants.len() != 1 {
-            bad_variant_count(tcx, adt, sp, def_id);
-            if adt.variants.is_empty() {
-                // Don't bother checking the fields. No variants (and thus no fields) exist.
-                return;
-            }
-        }
+    if adt.is_enum() && !tcx.features().transparent_enums {
+        feature_err(
+            &tcx.sess.parse_sess,
+            sym::transparent_enums,
+            sp,
+            "transparent enums are unstable",
+        )
+        .emit();
     }
 
     if adt.is_union() && !tcx.features().transparent_unions {
@@ -2401,6 +2392,14 @@ fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
         .emit();
     }
 
+    if adt.variants.len() != 1 {
+        bad_variant_count(tcx, adt, sp, def_id);
+        if adt.variants.is_empty() {
+            // Don't bother checking the fields. No variants (and thus no fields) exist.
+            return;
+        }
+    }
+
     // For each field, figure out if it's known to be a ZST and align(1)
     let field_infos = adt.all_fields().map(|field| {
         let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
@@ -5351,9 +5350,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                       directly, not through a function pointer");
     }
 
-    // Resolves `typ` by a single level if `typ` is a type variable.
-    // If no resolution is possible, then an error is reported.
-    // Numeric inference variables may be left unresolved.
+    /// Resolves `typ` by a single level if `typ` is a type variable.
+    /// If no resolution is possible, then an error is reported.
+    /// Numeric inference variables may be left unresolved.
     pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
         let ty = self.resolve_vars_with_obligations(ty);
         if !ty.is_ty_var() {
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 71d1cd869a6..4fb57a65625 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -1154,6 +1154,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.tcx.mk_ref(region, mt)
     }
 
+    /// Type check a slice pattern.
+    ///
+    /// Syntactically, these look like `[pat_0, ..., pat_n]`.
+    /// Semantically, we are type checking a pattern with structure:
+    /// ```
+    /// [before_0, ..., before_n, (slice, after_0, ... after_n)?]
+    /// ```
+    /// The type of `slice`, if it is present, depends on the `expected` type.
+    /// If `slice` is missing, then so is `after_i`.
+    /// If `slice` is present, it can still represent 0 elements.
     fn check_pat_slice(
         &self,
         span: Span,
@@ -1167,27 +1177,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let tcx = self.tcx;
         let expected_ty = self.structurally_resolved_type(span, expected);
         let (inner_ty, slice_ty) = match expected_ty.kind {
+            // An array, so we might have something like `let [a, b, c] = [0, 1, 2];`.
             ty::Array(inner_ty, size) => {
                 let slice_ty = if let Some(size) = size.try_eval_usize(tcx, self.param_env) {
+                    // Now we know the length...
                     let min_len = before.len() as u64 + after.len() as u64;
                     if slice.is_none() {
+                        // ...and since there is no variable-length pattern,
+                        // we require an exact match between the number of elements
+                        // in the array pattern and as provided by the matched type.
                         if min_len != size {
                             self.error_scrutinee_inconsistent_length(span, min_len, size)
                         }
                         tcx.types.err
                     } else if let Some(rest) = size.checked_sub(min_len) {
+                        // The variable-length pattern was there,
+                        // so it has an array type with the remaining elements left as its size...
                         tcx.mk_array(inner_ty, rest)
                     } else {
+                        // ...however, in this case, there were no remaining elements.
+                        // That is, the slice pattern requires more than the array type offers.
                         self.error_scrutinee_with_rest_inconsistent_length(span, min_len, size);
                         tcx.types.err
                     }
                 } else {
+                    // No idea what the length is, which happens if we have e.g.,
+                    // `let [a, b] = arr` where `arr: [T; N]` where `const N: usize`.
                     self.error_scrutinee_unfixed_length(span);
                     tcx.types.err
                 };
                 (inner_ty, slice_ty)
             }
             ty::Slice(inner_ty) => (inner_ty, expected_ty),
+            // The expected type must be an array or slice, but was neither, so error.
             _ => {
                 if !expected_ty.references_error() {
                     self.error_expected_array_or_slice(span, expected_ty);
@@ -1196,12 +1218,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         };
 
+        // Type check all the patterns before `slice`.
         for elt in before {
             self.check_pat(&elt, inner_ty, def_bm, discrim_span);
         }
+        // Type check the `slice`, if present, against its expected type.
         if let Some(slice) = slice {
             self.check_pat(&slice, slice_ty, def_bm, discrim_span);
         }
+        // Type check the elements after `slice`, if present.
         for elt in after {
             self.check_pat(&elt, inner_ty, def_bm, discrim_span);
         }
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 49a9cb093da..1459e8f37cd 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -2683,7 +2683,7 @@ function getSearchElement() {
         insertAfter(popup, getSearchElement());
     }
 
-    onHashChange();
+    onHashChange(null);
     window.onhashchange = onHashChange;
 
     buildHelperPopup();
diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs
index 5c022159970..c33f98bdd83 100644
--- a/src/libstd/net/tcp.rs
+++ b/src/libstd/net/tcp.rs
@@ -1313,21 +1313,6 @@ mod tests {
     }
 
     #[test]
-    fn fast_rebind() {
-        each_ip(&mut |addr| {
-            let acceptor = t!(TcpListener::bind(&addr));
-
-            let _t = thread::spawn(move || {
-                t!(TcpStream::connect(&addr));
-            });
-
-            t!(acceptor.accept());
-            drop(acceptor);
-            t!(TcpListener::bind(&addr));
-        });
-    }
-
-    #[test]
     fn tcp_clone_smoke() {
         each_ip(&mut |addr| {
             let acceptor = t!(TcpListener::bind(&addr));