about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/src/mir/interpret/pointer.rs14
-rw-r--r--compiler/rustc_parse/src/parser/item.rs15
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs5
-rw-r--r--library/core/src/cell.rs3
-rw-r--r--src/bootstrap/test.rs5
-rw-r--r--src/librustdoc/html/highlight.rs8
-rw-r--r--src/librustdoc/html/render/span_map.rs18
-rw-r--r--src/librustdoc/html/static/css/themes/ayu.css2
-rw-r--r--src/test/rustdoc-gui/code-sidebar-toggle.goml1
-rw-r--r--src/test/rustdoc-gui/jump-to-def-background.goml23
-rw-r--r--src/test/rustdoc-gui/src/link_to_definition/Cargo.lock7
-rw-r--r--src/test/rustdoc-gui/src/link_to_definition/Cargo.toml7
-rw-r--r--src/test/rustdoc-gui/src/link_to_definition/lib.rs6
-rw-r--r--src/test/rustdoc/check-source-code-urls-to-def-std.rs17
-rw-r--r--src/test/rustdoc/check-source-code-urls-to-def.rs8
-rw-r--r--src/test/ui/issues/issue-56031.stderr10
-rw-r--r--src/test/ui/parser/issue-88818.rs10
-rw-r--r--src/test/ui/parser/issue-88818.stderr18
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs13
19 files changed, 165 insertions, 25 deletions
diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs
index 3eee45a9230..c9dc5a0f3b5 100644
--- a/compiler/rustc_middle/src/mir/interpret/pointer.rs
+++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs
@@ -3,7 +3,7 @@ use super::{AllocId, InterpResult};
 use rustc_macros::HashStable;
 use rustc_target::abi::{HasDataLayout, Size};
 
-use std::convert::TryFrom;
+use std::convert::{TryFrom, TryInto};
 use std::fmt;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -20,29 +20,27 @@ pub trait PointerArithmetic: HasDataLayout {
 
     #[inline]
     fn machine_usize_max(&self) -> u64 {
-        let max_usize_plus_1 = 1u128 << self.pointer_size().bits();
-        u64::try_from(max_usize_plus_1 - 1).unwrap()
+        self.pointer_size().unsigned_int_max().try_into().unwrap()
     }
 
     #[inline]
     fn machine_isize_min(&self) -> i64 {
-        let max_isize_plus_1 = 1i128 << (self.pointer_size().bits() - 1);
-        i64::try_from(-max_isize_plus_1).unwrap()
+        self.pointer_size().signed_int_min().try_into().unwrap()
     }
 
     #[inline]
     fn machine_isize_max(&self) -> i64 {
-        let max_isize_plus_1 = 1u128 << (self.pointer_size().bits() - 1);
-        i64::try_from(max_isize_plus_1 - 1).unwrap()
+        self.pointer_size().signed_int_max().try_into().unwrap()
     }
 
     #[inline]
     fn machine_usize_to_isize(&self, val: u64) -> i64 {
         let val = val as i64;
-        // Now clamp into the machine_isize range.
+        // Now wrap-around into the machine_isize range.
         if val > self.machine_isize_max() {
             // This can only happen the the ptr size is < 64, so we know max_usize_plus_1 fits into
             // i64.
+            debug_assert!(self.pointer_size().bits() < 64);
             let max_usize_plus_1 = 1u128 << self.pointer_size().bits();
             val - i64::try_from(max_usize_plus_1).unwrap()
         } else {
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 10c73fd64bc..04a7948e8c9 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -493,7 +493,20 @@ impl<'a> Parser<'a> {
         let ty_first = if self.token.is_keyword(kw::For) && self.look_ahead(1, |t| t != &token::Lt)
         {
             let span = self.prev_token.span.between(self.token.span);
-            self.struct_span_err(span, "missing trait in a trait impl").emit();
+            self.struct_span_err(span, "missing trait in a trait impl")
+                .span_suggestion(
+                    span,
+                    "add a trait here",
+                    " Trait ".into(),
+                    Applicability::HasPlaceholders,
+                )
+                .span_suggestion(
+                    span.to(self.token.span),
+                    "for an inherent impl, drop this `for`",
+                    "".into(),
+                    Applicability::MaybeIncorrect,
+                )
+                .emit();
             P(Ty {
                 kind: TyKind::Path(None, err_path(span)),
                 span,
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index f5be8bf0949..8adf9015933 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1487,10 +1487,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ) => false,
 
             (ParamCandidate(other), ParamCandidate(victim)) => {
-                let value_same_except_bound_vars = other.value.skip_binder()
+                let same_except_bound_vars = other.value.skip_binder()
                     == victim.value.skip_binder()
+                    && other.constness == victim.constness
                     && !other.value.skip_binder().has_escaping_bound_vars();
-                if value_same_except_bound_vars {
+                if same_except_bound_vars {
                     // See issue #84398. In short, we can generate multiple ParamCandidates which are
                     // the same except for unused bound vars. Just pick the one with the fewest bound vars
                     // or the current one if tied (they should both evaluate to the same answer). This is
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 2adf6a549e6..e56b631dbaf 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -1916,7 +1916,8 @@ impl<T: ?Sized> UnsafeCell<T> {
     /// ```
     #[inline(always)]
     #[stable(feature = "unsafe_cell_get_mut", since = "1.50.0")]
-    pub fn get_mut(&mut self) -> &mut T {
+    #[rustc_const_unstable(feature = "const_unsafecell_get_mut", issue = "88836")]
+    pub const fn get_mut(&mut self) -> &mut T {
         &mut self.value
     }
 
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index d12e86b7c1d..386ffb384a8 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -925,6 +925,11 @@ impl Step for RustdocGUI {
                     .env("RUSTDOC", builder.rustdoc(self.compiler))
                     .env("RUSTC", builder.rustc(self.compiler))
                     .current_dir(path);
+                // FIXME: implement a `// compile-flags` command or similar
+                //        instead of hard-coding this test
+                if entry.file_name() == "link_to_definition" {
+                    cargo.env("RUSTDOCFLAGS", "-Zunstable-options --generate-link-to-definition");
+                }
                 builder.run(&mut cargo);
             }
         }
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index f8fc9243e14..ece3ee640e2 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -5,6 +5,7 @@
 //!
 //! Use the `render_with_highlighting` to highlight some rust code.
 
+use crate::clean::PrimitiveType;
 use crate::html::escape::Escape;
 use crate::html::render::Context;
 
@@ -584,6 +585,13 @@ fn string<T: Display>(
                             .ok()
                             .map(|(url, _, _)| url)
                     }
+                    LinkFromSrc::Primitive(prim) => format::href_with_root_path(
+                        PrimitiveType::primitive_locations(context.tcx())[&prim],
+                        context,
+                        Some(context_info.root_path),
+                    )
+                    .ok()
+                    .map(|(url, _, _)| url),
                 }
             })
         {
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index 54476d9c9a4..d517f3ac0e3 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -1,4 +1,4 @@
-use crate::clean;
+use crate::clean::{self, PrimitiveType};
 use crate::html::sources;
 
 use rustc_data_structures::fx::FxHashMap;
@@ -22,6 +22,7 @@ use std::path::{Path, PathBuf};
 crate enum LinkFromSrc {
     Local(clean::Span),
     External(DefId),
+    Primitive(PrimitiveType),
 }
 
 /// This function will do at most two things:
@@ -73,17 +74,20 @@ impl<'tcx> SpanMapVisitor<'tcx> {
                 Some(def_id)
             }
             Res::Local(_) => None,
+            Res::PrimTy(p) => {
+                // FIXME: Doesn't handle "path-like" primitives like arrays or tuples.
+                let span = path_span.unwrap_or(path.span);
+                self.matches.insert(span, LinkFromSrc::Primitive(PrimitiveType::from(p)));
+                return;
+            }
             Res::Err => return,
             _ => return,
         };
         if let Some(span) = self.tcx.hir().res_span(path.res) {
-            self.matches.insert(
-                path_span.unwrap_or_else(|| path.span),
-                LinkFromSrc::Local(clean::Span::new(span)),
-            );
-        } else if let Some(def_id) = info {
             self.matches
-                .insert(path_span.unwrap_or_else(|| path.span), LinkFromSrc::External(def_id));
+                .insert(path_span.unwrap_or(path.span), LinkFromSrc::Local(clean::Span::new(span)));
+        } else if let Some(def_id) = info {
+            self.matches.insert(path_span.unwrap_or(path.span), LinkFromSrc::External(def_id));
         }
     }
 }
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index f9ddef4120b..eada8f4a04d 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -217,7 +217,7 @@ a {
 	color: #c5c5c5;
 }
 body.source .example-wrap pre.rust a {
-	background: #c5c5c5;
+	background: #333;
 }
 
 .docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),
diff --git a/src/test/rustdoc-gui/code-sidebar-toggle.goml b/src/test/rustdoc-gui/code-sidebar-toggle.goml
index 00326e9bbc4..6fb92e19660 100644
--- a/src/test/rustdoc-gui/code-sidebar-toggle.goml
+++ b/src/test/rustdoc-gui/code-sidebar-toggle.goml
@@ -1,5 +1,6 @@
 goto: file://|DOC_PATH|/test_docs/index.html
 click: ".srclink"
+wait-for: "#sidebar-toggle"
 click: "#sidebar-toggle"
 wait-for: 500
 fail: true
diff --git a/src/test/rustdoc-gui/jump-to-def-background.goml b/src/test/rustdoc-gui/jump-to-def-background.goml
new file mode 100644
index 00000000000..3df899e0f26
--- /dev/null
+++ b/src/test/rustdoc-gui/jump-to-def-background.goml
@@ -0,0 +1,23 @@
+// We check the background color on the jump to definition links in the source code page.
+goto: file://|DOC_PATH|/src/link_to_definition/lib.rs.html
+
+// Set the theme to dark.
+local-storage: {"rustdoc-theme": "dark", "rustdoc-preferred-dark-theme": "dark", "rustdoc-use-system-theme": "false"}
+// We reload the page so the local storage settings are being used.
+reload:
+
+assert-css: ("body.source .example-wrap pre.rust a", {"background-color": "rgb(51, 51, 51)"}, ALL)
+
+// Set the theme to ayu.
+local-storage: {"rustdoc-theme": "ayu", "rustdoc-preferred-dark-theme": "ayu", "rustdoc-use-system-theme": "false"}
+// We reload the page so the local storage settings are being used.
+reload:
+
+assert-css: ("body.source .example-wrap pre.rust a", {"background-color": "rgb(51, 51, 51)"}, ALL)
+
+// Set the theme to light.
+local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
+// We reload the page so the local storage settings are being used.
+reload:
+
+assert-css: ("body.source .example-wrap pre.rust a", {"background-color": "rgb(238, 238, 238)"}, ALL)
diff --git a/src/test/rustdoc-gui/src/link_to_definition/Cargo.lock b/src/test/rustdoc-gui/src/link_to_definition/Cargo.lock
new file mode 100644
index 00000000000..e4b4e52d028
--- /dev/null
+++ b/src/test/rustdoc-gui/src/link_to_definition/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "link_to_definition"
+version = "0.1.0"
diff --git a/src/test/rustdoc-gui/src/link_to_definition/Cargo.toml b/src/test/rustdoc-gui/src/link_to_definition/Cargo.toml
new file mode 100644
index 00000000000..cdd294d74d3
--- /dev/null
+++ b/src/test/rustdoc-gui/src/link_to_definition/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "link_to_definition"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
diff --git a/src/test/rustdoc-gui/src/link_to_definition/lib.rs b/src/test/rustdoc-gui/src/link_to_definition/lib.rs
new file mode 100644
index 00000000000..de9ee66a2ba
--- /dev/null
+++ b/src/test/rustdoc-gui/src/link_to_definition/lib.rs
@@ -0,0 +1,6 @@
+pub struct Bar {
+    pub a: String,
+    pub b: u32,
+}
+
+pub fn foo(_b: &Bar) {}
diff --git a/src/test/rustdoc/check-source-code-urls-to-def-std.rs b/src/test/rustdoc/check-source-code-urls-to-def-std.rs
new file mode 100644
index 00000000000..b129ceb5b73
--- /dev/null
+++ b/src/test/rustdoc/check-source-code-urls-to-def-std.rs
@@ -0,0 +1,17 @@
+// compile-flags: -Zunstable-options --generate-link-to-definition
+
+#![crate_name = "foo"]
+
+// @has 'src/foo/check-source-code-urls-to-def-std.rs.html'
+
+fn babar() {}
+
+// @has - '//a[@href="{{channel}}/std/primitive.u32.html"]' 'u32'
+// @has - '//a[@href="{{channel}}/std/primitive.str.html"]' 'str'
+// @has - '//a[@href="{{channel}}/std/primitive.bool.html"]' 'bool'
+// @has - '//a[@href="../../src/foo/check-source-code-urls-to-def-std.rs.html#7"]' 'babar'
+pub fn foo(a: u32, b: &str, c: String) {
+    let x = 12;
+    let y: bool = true;
+    babar();
+}
diff --git a/src/test/rustdoc/check-source-code-urls-to-def.rs b/src/test/rustdoc/check-source-code-urls-to-def.rs
index e3ae79ccdb1..0cb8e423016 100644
--- a/src/test/rustdoc/check-source-code-urls-to-def.rs
+++ b/src/test/rustdoc/check-source-code-urls-to-def.rs
@@ -27,6 +27,8 @@ impl Foo {
 fn babar() {}
 
 // @has - '//a/@href' '/struct.String.html'
+// @has - '//a/@href' '/primitive.u32.html'
+// @has - '//a/@href' '/primitive.str.html'
 // @count - '//a[@href="../../src/foo/check-source-code-urls-to-def.rs.html#21"]' 5
 // @has - '//a[@href="../../source_code/struct.SourceCode.html"]' 'source_code::SourceCode'
 pub fn foo(a: u32, b: &str, c: String, d: Foo, e: bar::Bar, f: source_code::SourceCode) {
@@ -40,5 +42,9 @@ pub fn foo(a: u32, b: &str, c: String, d: Foo, e: bar::Bar, f: source_code::Sour
 
 // @has - '//a[@href="../../src/foo/auxiliary/source-code-bar.rs.html#14-16"]' 'bar::sub::Trait'
 // @has - '//a[@href="../../src/foo/auxiliary/source-code-bar.rs.html#14-16"]' 'Trait'
-pub fn foo2<T: bar::sub::Trait, V: Trait>(t: &T, v: &V) {
+pub fn foo2<T: bar::sub::Trait, V: Trait>(t: &T, v: &V, b: bool) {
 }
+
+// @has - '//a[@href="../../foo/primitive.bool.html"]' 'bool'
+#[doc(primitive = "bool")]
+mod whatever {}
diff --git a/src/test/ui/issues/issue-56031.stderr b/src/test/ui/issues/issue-56031.stderr
index 3d7acee0a56..7ee5bc6ec61 100644
--- a/src/test/ui/issues/issue-56031.stderr
+++ b/src/test/ui/issues/issue-56031.stderr
@@ -3,6 +3,16 @@ error: missing trait in a trait impl
    |
 LL | impl for T {}
    |     ^
+   |
+help: add a trait here
+   |
+LL | impl Trait for T {}
+   |      +++++
+help: for an inherent impl, drop this `for`
+   |
+LL - impl for T {}
+LL + impl T {}
+   | 
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-88818.rs b/src/test/ui/parser/issue-88818.rs
new file mode 100644
index 00000000000..b9233ca8339
--- /dev/null
+++ b/src/test/ui/parser/issue-88818.rs
@@ -0,0 +1,10 @@
+// Regression test for #88818 (improve error message for missing trait
+// in `impl for X`).
+
+struct S { }
+impl for S { }
+//~^ ERROR: missing trait in a trait impl
+//~| HELP: add a trait here
+//~| HELP: for an inherent impl, drop this `for`
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-88818.stderr b/src/test/ui/parser/issue-88818.stderr
new file mode 100644
index 00000000000..d30990ae582
--- /dev/null
+++ b/src/test/ui/parser/issue-88818.stderr
@@ -0,0 +1,18 @@
+error: missing trait in a trait impl
+  --> $DIR/issue-88818.rs:5:5
+   |
+LL | impl for S { }
+   |     ^
+   |
+help: add a trait here
+   |
+LL | impl Trait for S { }
+   |      +++++
+help: for an inherent impl, drop this `for`
+   |
+LL - impl for S { }
+LL + impl S { }
+   | 
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs
index 7185376b440..cc24dbd96d2 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs
@@ -16,12 +16,17 @@ impl const PartialEq for S {
 
 // This duplicate bound should not result in ambiguities. It should be equivalent to a single ~const
 // bound.
-// const fn equals_self<T: PartialEq + ~const PartialEq>(t: &T) -> bool {
-// FIXME(fee1-dead)^ why should the order matter here?
-const fn equals_self<T: ~const PartialEq + PartialEq>(t: &T) -> bool {
+const fn equals_self<T: PartialEq + ~const PartialEq>(t: &T) -> bool {
     *t == *t
 }
 
-pub const EQ: bool = equals_self(&S);
+trait A: PartialEq {}
+impl<T: PartialEq> A for T {}
+
+const fn equals_self2<T: A + ~const PartialEq>(t: &T) -> bool {
+    *t == *t
+}
+
+pub const EQ: bool = equals_self(&S) && equals_self2(&S);
 
 fn main() {}