Auto merge of #88914 - GuillaumeGomez:rollup-h5svc6w, r=GuillaumeGomez
Rollup of 7 pull requests Successful merges: - #88033 (Add links for primitives in "jump to definition" feature) - #88722 (Make `UnsafeCell::get_mut` const) - #88851 (Fix duplicate bounds for const_trait_impl) - #88859 (interpreter PointerArithmetic: use new Size helper methods) - #88885 (Fix jump def background) - #88894 (Improve error message for missing trait in trait impl) - #88896 (Reduce possibility of flaky tests) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
ec9a1bdc45
@ -3,7 +3,7 @@
|
||||
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 @@ fn pointer_size(&self) -> Size {
|
||||
|
||||
#[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 {
|
||||
|
@ -493,7 +493,20 @@ fn parse_item_impl(
|
||||
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,
|
||||
|
@ -1487,10 +1487,11 @@ fn candidate_should_be_dropped_in_favor_of(
|
||||
) => 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
|
||||
|
@ -1916,7 +1916,8 @@ pub const fn get(&self) -> *mut 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
|
||||
}
|
||||
|
||||
|
@ -925,6 +925,11 @@ fn run(self, builder: &Builder<'_>) {
|
||||
.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);
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
}
|
||||
})
|
||||
{
|
||||
|
@ -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 @@
|
||||
crate enum LinkFromSrc {
|
||||
Local(clean::Span),
|
||||
External(DefId),
|
||||
Primitive(PrimitiveType),
|
||||
}
|
||||
|
||||
/// This function will do at most two things:
|
||||
@ -73,17 +74,20 @@ fn handle_path(&mut self, path: &rustc_hir::Path<'_>, path_span: Option<Span>) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
23
src/test/rustdoc-gui/jump-to-def-background.goml
Normal file
23
src/test/rustdoc-gui/jump-to-def-background.goml
Normal file
@ -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)
|
7
src/test/rustdoc-gui/src/link_to_definition/Cargo.lock
Normal file
7
src/test/rustdoc-gui/src/link_to_definition/Cargo.lock
Normal file
@ -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"
|
7
src/test/rustdoc-gui/src/link_to_definition/Cargo.toml
Normal file
7
src/test/rustdoc-gui/src/link_to_definition/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "link_to_definition"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
6
src/test/rustdoc-gui/src/link_to_definition/lib.rs
Normal file
6
src/test/rustdoc-gui/src/link_to_definition/lib.rs
Normal file
@ -0,0 +1,6 @@
|
||||
pub struct Bar {
|
||||
pub a: String,
|
||||
pub b: u32,
|
||||
}
|
||||
|
||||
pub fn foo(_b: &Bar) {}
|
17
src/test/rustdoc/check-source-code-urls-to-def-std.rs
Normal file
17
src/test/rustdoc/check-source-code-urls-to-def-std.rs
Normal file
@ -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();
|
||||
}
|
@ -27,6 +27,8 @@ fn hello(&self) {}
|
||||
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 {}
|
||||
|
@ -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
|
||||
|
||||
|
10
src/test/ui/parser/issue-88818.rs
Normal file
10
src/test/ui/parser/issue-88818.rs
Normal file
@ -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() {}
|
18
src/test/ui/parser/issue-88818.stderr
Normal file
18
src/test/ui/parser/issue-88818.stderr
Normal file
@ -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
|
||||
|
@ -16,12 +16,17 @@ fn ne(&self, other: &S) -> bool {
|
||||
|
||||
// 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() {}
|
||||
|
Loading…
Reference in New Issue
Block a user