about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--library/alloc/src/vec.rs2
-rw-r--r--library/core/src/ptr/const_ptr.rs17
-rw-r--r--library/core/src/ptr/mut_ptr.rs17
-rw-r--r--library/std/src/net/ip.rs23
-rw-r--r--src/ci/github-actions/ci.yml12
-rw-r--r--src/librustc_attr/Cargo.toml1
-rw-r--r--src/librustc_attr/builtin.rs12
-rw-r--r--src/librustc_expand/proc_macro_server.rs10
-rw-r--r--src/librustc_lexer/src/lib.rs10
-rw-r--r--src/librustc_lint/lib.rs2
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/librustdoc/clean/types.rs2
-rw-r--r--src/librustdoc/html/render/mod.rs30
-rw-r--r--src/librustdoc/html/static/main.js4
15 files changed, 88 insertions, 57 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 3f8bf0ac8e8..e2a16d56e49 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3257,6 +3257,7 @@ dependencies = [
  "rustc_data_structures",
  "rustc_errors",
  "rustc_feature",
+ "rustc_lexer",
  "rustc_macros",
  "rustc_serialize",
  "rustc_session",
diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs
index 786d1b6ba82..de707a71a8c 100644
--- a/library/alloc/src/vec.rs
+++ b/library/alloc/src/vec.rs
@@ -2269,7 +2269,7 @@ impl<T> Vec<T> {
     /// with the given `replace_with` iterator and yields the removed items.
     /// `replace_with` does not need to be the same length as `range`.
     ///
-    /// The element range is removed even if the iterator is not consumed until the end.
+    /// `range` is removed even if the iterator is not consumed until the end.
     ///
     /// It is unspecified how many elements are removed from the vector
     /// if the `Splice` value is leaked.
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index a16970e9fd1..ac20897d258 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -662,6 +662,11 @@ impl<T: ?Sized> *const T {
     /// will only affect the pointer part, whereas for (thin) pointers to
     /// sized types, this has the same effect as a simple assignment.
     ///
+    /// The resulting pointer will have provenance of `val`, i.e., for a fat
+    /// pointer, this operation is semantically the same as creating a new
+    /// fat pointer with the data pointer value of `val` but the metadata of
+    /// `self`.
+    ///
     /// # Examples
     ///
     /// This function is primarily useful for allowing byte-wise pointer
@@ -673,13 +678,17 @@ impl<T: ?Sized> *const T {
     /// let arr: [i32; 3] = [1, 2, 3];
     /// let mut ptr = &arr[0] as *const dyn Debug;
     /// let thin = ptr as *const u8;
-    /// ptr = ptr.set_ptr_value(unsafe { thin.add(8).cast() });
-    /// assert_eq!(unsafe { *(ptr as *const i32) }, 3);
+    /// unsafe {
+    ///     ptr = ptr.set_ptr_value(thin.add(8));
+    ///     # assert_eq!(*(ptr as *const i32), 3);
+    ///     println!("{:?}", &*ptr); // will print "3"
+    /// }
     /// ```
     #[unstable(feature = "set_ptr_value", issue = "75091")]
+    #[must_use = "returns a new pointer rather than modifying its argument"]
     #[inline]
-    pub fn set_ptr_value(mut self, val: *const ()) -> Self {
-        let thin = &mut self as *mut *const T as *mut *const ();
+    pub fn set_ptr_value(mut self, val: *const u8) -> Self {
+        let thin = &mut self as *mut *const T as *mut *const u8;
         // SAFETY: In case of a thin pointer, this operations is identical
         // to a simple assignment. In case of a fat pointer, with the current
         // fat pointer layout implementation, the first field of such a
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index b47f90c5996..df00139118a 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -718,6 +718,11 @@ impl<T: ?Sized> *mut T {
     /// will only affect the pointer part, whereas for (thin) pointers to
     /// sized types, this has the same effect as a simple assignment.
     ///
+    /// The resulting pointer will have provenance of `val`, i.e., for a fat
+    /// pointer, this operation is semantically the same as creating a new
+    /// fat pointer with the data pointer value of `val` but the metadata of
+    /// `self`.
+    ///
     /// # Examples
     ///
     /// This function is primarily useful for allowing byte-wise pointer
@@ -729,13 +734,17 @@ impl<T: ?Sized> *mut T {
     /// let mut arr: [i32; 3] = [1, 2, 3];
     /// let mut ptr = &mut arr[0] as *mut dyn Debug;
     /// let thin = ptr as *mut u8;
-    /// ptr = ptr.set_ptr_value(unsafe { thin.add(8).cast() });
-    /// assert_eq!(unsafe { *(ptr as *mut i32) }, 3);
+    /// unsafe {
+    ///     ptr = ptr.set_ptr_value(thin.add(8));
+    ///     # assert_eq!(*(ptr as *mut i32), 3);
+    ///     println!("{:?}", &*ptr); // will print "3"
+    /// }
     /// ```
     #[unstable(feature = "set_ptr_value", issue = "75091")]
+    #[must_use = "returns a new pointer rather than modifying its argument"]
     #[inline]
-    pub fn set_ptr_value(mut self, val: *mut ()) -> Self {
-        let thin = &mut self as *mut *mut T as *mut *mut ();
+    pub fn set_ptr_value(mut self, val: *mut u8) -> Self {
+        let thin = &mut self as *mut *mut T as *mut *mut u8;
         // SAFETY: In case of a thin pointer, this operations is identical
         // to a simple assignment. In case of a fat pointer, with the current
         // fat pointer layout implementation, the first field of such a
diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs
index 5d103e64037..ccaacbf1a58 100644
--- a/library/std/src/net/ip.rs
+++ b/library/std/src/net/ip.rs
@@ -767,10 +767,8 @@ impl Ipv4Addr {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_ipv6_compatible(&self) -> Ipv6Addr {
-        let octets = self.octets();
-        Ipv6Addr::from([
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, octets[0], octets[1], octets[2], octets[3],
-        ])
+        let [a, b, c, d] = self.octets();
+        Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d])
     }
 
     /// Converts this address to an IPv4-mapped [IPv6 address].
@@ -789,10 +787,8 @@ impl Ipv4Addr {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_ipv6_mapped(&self) -> Ipv6Addr {
-        let octets = self.octets();
-        Ipv6Addr::from([
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, octets[0], octets[1], octets[2], octets[3],
-        ])
+        let [a, b, c, d] = self.octets();
+        Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d])
     }
 }
 
@@ -1498,11 +1494,12 @@ impl Ipv6Addr {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_ipv4(&self) -> Option<Ipv4Addr> {
-        match self.segments() {
-            [0, 0, 0, 0, 0, f, g, h] if f == 0 || f == 0xffff => {
-                Some(Ipv4Addr::new((g >> 8) as u8, g as u8, (h >> 8) as u8, h as u8))
-            }
-            _ => None,
+        if let [0, 0, 0, 0, 0, 0 | 0xffff, ab, cd] = self.segments() {
+            let [a, b] = ab.to_be_bytes();
+            let [c, d] = cd.to_be_bytes();
+            Some(Ipv4Addr::new(a, b, c, d))
+        } else {
+            None
         }
     }
 
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 0ff77de003d..165ecc79180 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -490,15 +490,17 @@ jobs:
 
           # 32/64-bit MinGW builds.
           #
-          # We are using MinGW with posix threads since LLVM does not compile with
-          # the win32 threads version due to missing support for C++'s std::thread.
+          # We are using MinGW with POSIX threads since LLVM requires
+          # C++'s std::thread which is disabled in libstdc++ with win32 threads.
+          # FIXME: Libc++ doesn't have this limitation so we can avoid 
+          # winpthreads if we switch to it.
           #
-          # Instead of relying on the MinGW version installed on appveryor we download
-          # and install one ourselves so we won't be surprised by changes to appveyor's
+          # Instead of relying on the MinGW version installed on CI we download
+          # and install one ourselves so we won't be surprised by changes to CI's
           # build image.
           #
           # Finally, note that the downloads below are all in the `rust-lang-ci` S3
-          # bucket, but they cleraly didn't originate there! The downloads originally
+          # bucket, but they clearly didn't originate there! The downloads originally
           # came from the mingw-w64 SourceForge download site. Unfortunately
           # SourceForge is notoriously flaky, so we mirror it on our own infrastructure.
 
diff --git a/src/librustc_attr/Cargo.toml b/src/librustc_attr/Cargo.toml
index 496becb8f1b..35bdf747f08 100644
--- a/src/librustc_attr/Cargo.toml
+++ b/src/librustc_attr/Cargo.toml
@@ -16,6 +16,7 @@ rustc_errors = { path = "../librustc_errors" }
 rustc_span = { path = "../librustc_span" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_feature = { path = "../librustc_feature" }
+rustc_lexer = { path = "../librustc_lexer" }
 rustc_macros = { path = "../librustc_macros" }
 rustc_session = { path = "../librustc_session" }
 rustc_ast = { path = "../librustc_ast" }
diff --git a/src/librustc_attr/builtin.rs b/src/librustc_attr/builtin.rs
index 552584bb4d0..5f131fae385 100644
--- a/src/librustc_attr/builtin.rs
+++ b/src/librustc_attr/builtin.rs
@@ -20,6 +20,7 @@ enum AttrError {
     MultipleItem(String),
     UnknownMetaItem(String, &'static [&'static str]),
     MissingSince,
+    NonIdentFeature,
     MissingFeature,
     MultipleStabilityLevels,
     UnsupportedLiteral(&'static str, /* is_bytestr */ bool),
@@ -40,6 +41,9 @@ fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) {
         AttrError::MissingSince => {
             struct_span_err!(diag, span, E0542, "missing 'since'").emit();
         }
+        AttrError::NonIdentFeature => {
+            struct_span_err!(diag, span, E0546, "'feature' is not an identifier").emit();
+        }
         AttrError::MissingFeature => {
             struct_span_err!(diag, span, E0546, "missing 'feature'").emit();
         }
@@ -344,6 +348,14 @@ where
 
                     match (feature, reason, issue) {
                         (Some(feature), reason, Some(_)) => {
+                            if !rustc_lexer::is_ident(&feature.as_str()) {
+                                handle_errors(
+                                    &sess.parse_sess,
+                                    attr.span,
+                                    AttrError::NonIdentFeature,
+                                );
+                                continue;
+                            }
                             let level = Unstable { reason, issue: issue_num, is_soft };
                             if sym::unstable == meta_name {
                                 stab = Some(Stability { level, feature });
diff --git a/src/librustc_expand/proc_macro_server.rs b/src/librustc_expand/proc_macro_server.rs
index dc7ba2d0424..83a650443bc 100644
--- a/src/librustc_expand/proc_macro_server.rs
+++ b/src/librustc_expand/proc_macro_server.rs
@@ -319,18 +319,10 @@ pub struct Ident {
 }
 
 impl Ident {
-    fn is_valid(string: &str) -> bool {
-        let mut chars = string.chars();
-        if let Some(start) = chars.next() {
-            rustc_lexer::is_id_start(start) && chars.all(rustc_lexer::is_id_continue)
-        } else {
-            false
-        }
-    }
     fn new(sess: &ParseSess, sym: Symbol, is_raw: bool, span: Span) -> Ident {
         let sym = nfc_normalize(&sym.as_str());
         let string = sym.as_str();
-        if !Self::is_valid(&string) {
+        if !rustc_lexer::is_ident(&string) {
             panic!("`{:?}` is not a valid identifier", string)
         }
         if is_raw && !sym.can_be_raw() {
diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs
index 862ffd50d38..7949a232b9b 100644
--- a/src/librustc_lexer/src/lib.rs
+++ b/src/librustc_lexer/src/lib.rs
@@ -274,6 +274,16 @@ pub fn is_id_continue(c: char) -> bool {
         || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_continue(c))
 }
 
+/// The passed string is lexically an identifier.
+pub fn is_ident(string: &str) -> bool {
+    let mut chars = string.chars();
+    if let Some(start) = chars.next() {
+        is_id_start(start) && chars.all(is_id_continue)
+    } else {
+        false
+    }
+}
+
 impl Cursor<'_> {
     /// Parses a token from the input string.
     fn advance_token(&mut self) -> Token {
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 15a9affbff7..1f17c7dcba4 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -219,7 +219,7 @@ pub fn new_lint_store(no_interleave_lints: bool, internal_lints: bool) -> LintSt
 
 /// Tell the `LintStore` about all the built-in lints (the ones
 /// defined in this crate and the ones defined in
-/// `rustc::lint::builtin`).
+/// `rustc_session::lint::builtin`).
 fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
     macro_rules! add_lint_group {
         ($name:expr, $($lint:ident),*) => (
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 3afd3671d6b..801d06e6101 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2358,7 +2358,7 @@ impl Clean<Stability> for attr::Stability {
     fn clean(&self, _: &DocContext<'_>) -> Stability {
         Stability {
             level: stability::StabilityLevel::from_attr_level(&self.level),
-            feature: Some(self.feature.to_string()).filter(|f| !f.is_empty()),
+            feature: self.feature.to_string(),
             since: match self.level {
                 attr::Stable { ref since } => since.to_string(),
                 _ => String::new(),
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 50eca75d7ca..627f88df45c 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1525,7 +1525,7 @@ pub struct ProcMacro {
 #[derive(Clone, Debug)]
 pub struct Stability {
     pub level: stability::StabilityLevel,
-    pub feature: Option<String>,
+    pub feature: String,
     pub since: String,
     pub unstable_reason: Option<String>,
     pub issue: Option<NonZeroU32>,
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 36357539692..bd919205dd1 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2144,7 +2144,7 @@ fn stability_tags(item: &clean::Item) -> String {
     if item
         .stability
         .as_ref()
-        .map(|s| s.level == stability::Unstable && s.feature.as_deref() != Some("rustc_private"))
+        .map(|s| s.level == stability::Unstable && s.feature != "rustc_private")
         == Some(true)
     {
         tags += &tag_html("unstable", "Experimental");
@@ -2195,25 +2195,25 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
 
     // Render unstable items. But don't render "rustc_private" crates (internal compiler crates).
     // Those crates are permanently unstable so it makes no sense to render "unstable" everywhere.
-    if let Some(stab) = item.stability.as_ref().filter(|stab| {
-        stab.level == stability::Unstable && stab.feature.as_deref() != Some("rustc_private")
-    }) {
+    if let Some(stab) = item
+        .stability
+        .as_ref()
+        .filter(|stab| stab.level == stability::Unstable && stab.feature != "rustc_private")
+    {
         let mut message =
             "<span class='emoji'>🔬</span> This is a nightly-only experimental API.".to_owned();
 
-        if let Some(feature) = stab.feature.as_deref() {
-            let mut feature = format!("<code>{}</code>", Escape(&feature));
-            if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, stab.issue) {
-                feature.push_str(&format!(
-                    "&nbsp;<a href=\"{url}{issue}\">#{issue}</a>",
-                    url = url,
-                    issue = issue
-                ));
-            }
-
-            message.push_str(&format!(" ({})", feature));
+        let mut feature = format!("<code>{}</code>", Escape(&stab.feature));
+        if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, stab.issue) {
+            feature.push_str(&format!(
+                "&nbsp;<a href=\"{url}{issue}\">#{issue}</a>",
+                url = url,
+                issue = issue
+            ));
         }
 
+        message.push_str(&format!(" ({})", feature));
+
         if let Some(unstable_reason) = &stab.unstable_reason {
             let mut ids = cx.id_map.borrow_mut();
             message = format!(
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 63853e7394b..462a696dee6 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -408,9 +408,7 @@ function defocusSearchBar() {
                 break;
 
             case "?":
-                if (ev.shiftKey) {
-                    displayHelp(true, ev);
-                }
+                displayHelp(true, ev);
                 break;
             }
         }