Auto merge of #86379 - JohnTitor:rollup-mkz9x36, r=JohnTitor

Rollup of 10 pull requests

Successful merges:

 - #85870 (Allow whitespace in dump_mir filter)
 - #86104 (Fix span calculation in format strings)
 - #86140 (Mention the `Borrow` guarantee on the `Hash` implementations for Arrays and `Vec`)
 - #86141 (Link reference in `dyn` keyword documentation)
 - #86260 (Open trait implementations' toggles by default.)
 - #86339 (Mention #79078 on compatibility notes of 1.52)
 - #86341 (Stop returning a value from `report_assert_as_lint`)
 - #86353 (Remove `projection_ty_from_predicates`)
 - #86361 (Add missing backslashes to prevent unwanted newlines in rustdoc HTML)
 - #86372 (Typo correction: s/is/its)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-06-16 22:48:31 +00:00
commit 444a85ac38
19 changed files with 136 additions and 63 deletions

View File

@ -306,6 +306,7 @@ Compatibility Notes
- [Rustc now catches more cases of `pub_use_of_private_extern_crate`][80763]
- [Changes in how proc macros handle whitespace may lead to panics when used
with older `proc-macro-hack` versions. A `cargo update` should be sufficient to fix this in all cases.][84136]
- [Turn `#[derive]` into a regular macro attribute][79078]
[84136]: https://github.com/rust-lang/rust/issues/84136
[80763]: https://github.com/rust-lang/rust/pull/80763
@ -332,6 +333,7 @@ Compatibility Notes
[78429]: https://github.com/rust-lang/rust/pull/78429
[82733]: https://github.com/rust-lang/rust/pull/82733
[82594]: https://github.com/rust-lang/rust/pull/82594
[79078]: https://github.com/rust-lang/rust/pull/79078
[cargo/9181]: https://github.com/rust-lang/cargo/pull/9181
[`char::MAX`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.MAX
[`char::REPLACEMENT_CHARACTER`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.REPLACEMENT_CHARACTER

View File

@ -939,6 +939,7 @@ pub fn expand_preparsed_format_args(
let msg = "format argument must be a string literal";
let fmt_sp = efmt.span;
let efmt_kind_is_lit: bool = matches!(efmt.kind, ast::ExprKind::Lit(_));
let (fmt_str, fmt_style, fmt_span) = match expr_to_spanned_string(ecx, efmt, msg) {
Ok(mut fmt) if append_newline => {
fmt.0 = Symbol::intern(&format!("{}\n", fmt.0));
@ -989,7 +990,19 @@ pub fn expand_preparsed_format_args(
if !parser.errors.is_empty() {
let err = parser.errors.remove(0);
let sp = fmt_span.from_inner(err.span);
let sp = if efmt_kind_is_lit {
fmt_span.from_inner(err.span)
} else {
// The format string could be another macro invocation, e.g.:
// format!(concat!("abc", "{}"), 4);
// However, `err.span` is an inner span relative to the *result* of
// the macro invocation, which is why we would get a nonsensical
// result calling `fmt_span.from_inner(err.span)` as above, and
// might even end up inside a multibyte character (issue #86085).
// Therefore, we conservatively report the error for the entire
// argument span here.
fmt_span
};
let mut e = ecx.struct_span_err(sp, &format!("invalid format string: {}", err.description));
e.span_label(sp, err.label + " in format string");
if let Some(note) = err.note {

View File

@ -285,7 +285,7 @@ pub mod label_strs {
// required that their size stay the same, but we don't want to change
// it inadvertently. This assert just ensures we're aware of any change.
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
static_assert_size!(DepNode, 18);
static_assert_size!(DepNode, 17);
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
static_assert_size!(DepNode, 24);

View File

@ -191,10 +191,6 @@
desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) }
}
query projection_ty_from_predicates(key: (DefId, DefId)) -> Option<ty::ProjectionTy<'tcx>> {
desc { |tcx| "finding projection type inside predicates of `{}`", tcx.def_path_str(key.0) }
}
query native_libraries(_: CrateNum) -> Lrc<Vec<NativeLib>> {
desc { "looking up the native libraries of a linked crate" }
}

View File

@ -528,14 +528,14 @@ fn report_assert_as_lint(
source_info: SourceInfo,
message: &'static str,
panic: AssertKind<impl std::fmt::Debug>,
) -> Option<()> {
let lint_root = self.lint_root(source_info)?;
) {
if let Some(lint_root) = self.lint_root(source_info) {
self.tcx.struct_span_lint_hir(lint, lint_root, source_info.span, |lint| {
let mut err = lint.build(message);
err.span_label(source_info.span, format!("{:?}", panic));
err.emit()
});
None
}
}
fn check_unary_op(
@ -557,7 +557,8 @@ fn check_unary_op(
source_info,
"this arithmetic operation will overflow",
AssertKind::OverflowNeg(val.to_const_int()),
)?;
);
return None;
}
Some(())
@ -602,7 +603,8 @@ fn check_binary_op(
},
r.to_const_int(),
),
)?;
);
return None;
}
}
@ -617,7 +619,8 @@ fn check_binary_op(
source_info,
"this arithmetic operation will overflow",
AssertKind::Overflow(op, l.to_const_int(), r.to_const_int()),
)?;
);
return None;
}
}
Some(())

View File

@ -99,7 +99,10 @@ pub fn dump_enabled<'tcx>(tcx: TyCtxt<'tcx>, pass_name: &str, def_id: DefId) ->
});
filters.split('|').any(|or_filter| {
or_filter.split('&').all(|and_filter| {
and_filter == "all" || pass_name.contains(and_filter) || node_path.contains(and_filter)
let and_filter_trimmed = and_filter.trim();
and_filter_trimmed == "all"
|| pass_name.contains(and_filter_trimmed)
|| node_path.contains(and_filter_trimmed)
})
})
}

View File

@ -77,7 +77,6 @@ pub fn provide(providers: &mut Providers) {
generics_of,
predicates_of,
predicates_defined_on,
projection_ty_from_predicates,
explicit_predicates_of,
super_predicates_of,
super_predicates_that_define_assoc_type,
@ -2352,29 +2351,6 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
}
}
fn projection_ty_from_predicates(
tcx: TyCtxt<'tcx>,
key: (
// ty_def_id
DefId,
// def_id of `N` in `<T as Trait>::N`
DefId,
),
) -> Option<ty::ProjectionTy<'tcx>> {
let (ty_def_id, item_def_id) = key;
let mut projection_ty = None;
for (predicate, _) in tcx.predicates_of(ty_def_id).predicates {
if let ty::PredicateKind::Projection(projection_predicate) = predicate.kind().skip_binder()
{
if item_def_id == projection_predicate.projection_ty.item_def_id {
projection_ty = Some(projection_predicate.projection_ty);
break;
}
}
}
projection_ty
}
/// Converts a specific `GenericBound` from the AST into a set of
/// predicates that apply to the self type. A vector is returned
/// because this can be anywhere from zero predicates (`T: ?Sized` adds no

View File

@ -2407,6 +2407,23 @@ fn clone_from(&mut self, other: &Self) {
}
}
/// The hash of a vector is the same as that of the corresponding slice,
/// as required by the `core::borrow::Borrow` implementation.
///
/// ```
/// use std::hash::{BuildHasher, Hash, Hasher};
///
/// fn hash_of(x: impl Hash, b: &impl BuildHasher) -> u64 {
/// let mut h = b.build_hasher();
/// x.hash(&mut h);
/// h.finish()
/// }
///
/// let b = std::collections::hash_map::RandomState::new();
/// let v: Vec<u8> = vec![0xa8, 0x3c, 0x09];
/// let s: &[u8] = &[0xa8, 0x3c, 0x09];
/// assert_eq!(hash_of(v, &b), hash_of(s, &b));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Hash, A: Allocator> Hash for Vec<T, A> {
#[inline]

View File

@ -139,6 +139,23 @@ fn borrow_mut(&mut self) -> &mut [T] {
}
}
/// The hash of an array is the same as that of the corresponding slice,
/// as required by the `Borrow` implementation.
///
/// ```
/// use std::hash::{BuildHasher, Hash, Hasher};
///
/// fn hash_of(x: impl Hash, b: &impl BuildHasher) -> u64 {
/// let mut h = b.build_hasher();
/// x.hash(&mut h);
/// h.finish()
/// }
///
/// let b = std::collections::hash_map::RandomState::new();
/// let a: [u8; 3] = [0xa8, 0x3c, 0x09];
/// let s: &[u8] = &[0xa8, 0x3c, 0x09];
/// assert_eq!(hash_of(a, &b), hash_of(s, &b));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Hash, const N: usize> Hash for [T; N] {
fn hash<H: hash::Hasher>(&self, state: &mut H) {

View File

@ -194,7 +194,7 @@ pub const fn from_raw_parts(
}
}
/// Decompose a (possibly wide) pointer into is address and metadata components.
/// Decompose a (possibly wide) pointer into its address and metadata components.
///
/// The pointer can be later reconstructed with [`NonNull::from_raw_parts`].
#[unstable(feature = "ptr_metadata", issue = "81513")]

View File

@ -2256,6 +2256,9 @@ mod await_keyword {}
/// At run-time, when a method needs to be called on the `dyn Trait`, the vtable is consulted to get
/// the function pointer and then that function pointer is called.
///
/// See the Reference for more information on [trait objects][ref-trait-obj]
/// and [object safety][ref-obj-safety].
///
/// ## Trade-offs
///
/// The above indirection is the additional runtime cost of calling a function on a `dyn Trait`.
@ -2264,9 +2267,9 @@ mod await_keyword {}
/// However, `dyn Trait` is likely to produce smaller code than `impl Trait` / generic parameters as
/// the method won't be duplicated for each concrete type.
///
/// Read more about `object safety` and [trait object]s.
///
/// [trait object]: ../book/ch17-02-trait-objects.html
/// [ref-trait-obj]: ../reference/types/trait-object.html
/// [ref-obj-safety]: ../reference/items/traits.html#object-safety
/// [erased]: https://en.wikipedia.org/wiki/Type_erasure
mod dyn_keyword {}

View File

@ -488,7 +488,7 @@ fn settings(root_path: &str, suffix: &str, themes: &[StylePath]) -> Result<Strin
.into(),
("auto-hide-large-items", "Auto-hide item contents for large items.", true).into(),
("auto-hide-method-docs", "Auto-hide item methods' documentation", false).into(),
("auto-hide-trait-implementations", "Auto-hide trait implementation documentation", true)
("auto-hide-trait-implementations", "Auto-hide trait implementation documentation", false)
.into(),
("auto-collapse-implementors", "Auto-hide implementors of a trait", true).into(),
("go-to-only-result", "Directly go to item in search if there is only one result", false)
@ -1543,16 +1543,11 @@ fn render_default_items(
}
}
if render_mode == RenderMode::Normal {
let is_implementing_trait = i.inner_impl().trait_.is_some();
let toggled = !impl_items.is_empty() || !default_impl_items.is_empty();
if toggled {
close_tags.insert_str(0, "</details>");
if is_implementing_trait {
write!(w, "<details class=\"rustdoc-toggle implementors-toggle\">");
} else {
write!(w, "<details class=\"rustdoc-toggle implementors-toggle\" open>");
}
}
if toggled {
write!(w, "<summary>")
}

View File

@ -864,7 +864,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni
if fields.peek().is_some() {
write!(
w,
"<h2 id=\"fields\" class=\"fields small-section-header\">
"<h2 id=\"fields\" class=\"fields small-section-header\">\
Fields<a href=\"#fields\" class=\"anchor\"></a></h2>"
);
for (field, ty) in fields {
@ -953,8 +953,8 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
if !e.variants.is_empty() {
write!(
w,
"<h2 id=\"variants\" class=\"variants small-section-header\">
Variants{}<a href=\"#variants\" class=\"anchor\"></a></h2>\n",
"<h2 id=\"variants\" class=\"variants small-section-header\">\
Variants{}<a href=\"#variants\" class=\"anchor\"></a></h2>",
document_non_exhaustive_header(it)
);
document_non_exhaustive(w, it);
@ -1139,7 +1139,7 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
if fields.peek().is_some() {
write!(
w,
"<h2 id=\"fields\" class=\"fields small-section-header\">
"<h2 id=\"fields\" class=\"fields small-section-header\">\
Fields{}<a href=\"#fields\" class=\"anchor\"></a></h2>",
document_non_exhaustive_header(it)
);

View File

@ -779,25 +779,25 @@ function hideThemeButtonState() {
var hideMethodDocs = getSettingValue("auto-hide-method-docs") === "true";
var hideImplementors = getSettingValue("auto-collapse-implementors") !== "false";
var hideImplementations = getSettingValue("auto-hide-trait-implementations") !== "false";
var hideImplementations = getSettingValue("auto-hide-trait-implementations") === "true";
var hideLargeItemContents = getSettingValue("auto-hide-large-items") !== "false";
function openImplementors(id) {
function setImplementorsTogglesOpen(id, open) {
var list = document.getElementById(id);
if (list !== null) {
onEachLazy(list.getElementsByClassName("implementors-toggle"), function(e) {
e.open = true;
e.open = open;
});
}
}
if (!hideImplementations) {
openImplementors("trait-implementations-list");
openImplementors("blanket-implementations-list");
if (hideImplementations) {
setImplementorsTogglesOpen("trait-implementations-list", false);
setImplementorsTogglesOpen("blanket-implementations-list", false);
}
if (!hideImplementors) {
openImplementors("implementors-list");
setImplementorsTogglesOpen("implementors-list", true);
}
onEachLazy(document.getElementsByClassName("rustdoc-toggle"), function (e) {

View File

@ -0,0 +1,5 @@
// This tests that the "implementations" section on struct/enum pages
// has all the implementations toggled open by default, so users can
// find method names in those implementations with Ctrl-F.
goto: file://|DOC_PATH|/test_docs/struct.Foo.html
assert: (".rustdoc-toggle.implementors-toggle", "open", "")

View File

@ -0,0 +1,15 @@
// If the format string is another macro invocation, rustc would previously
// compute nonsensical spans, such as:
//
// error: invalid format string: unmatched `}` found
// --> test.rs:2:17
// |
// 2 | format!(concat!("abc}"));
// | ^ unmatched `}` in format string
//
// This test checks that this behavior has been fixed.
fn main() {
format!(concat!("abc}"));
//~^ ERROR: invalid format string: unmatched `}` found
}

View File

@ -0,0 +1,11 @@
error: invalid format string: unmatched `}` found
--> $DIR/format-concat-span.rs:13:13
|
LL | format!(concat!("abc}"));
| ^^^^^^^^^^^^^^^ unmatched `}` in format string
|
= note: if you intended to print `}`, you can escape it using `}}`
= note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error

View File

@ -0,0 +1,6 @@
// Tests for an ICE with the fuzzed input below.
fn main ( ) {
format ! ( concat ! ( r#"lJ𐏿Æ<F0908FBF>.𐏿<>"# , "r} {}" ) ) ;
//~^ ERROR: invalid format string: unmatched `}` found
}

View File

@ -0,0 +1,11 @@
error: invalid format string: unmatched `}` found
--> $DIR/issue-86085.rs:4:12
|
LL | format ! ( concat ! ( r#"lJ𐏿Æ<F0908FBF>.𐏿<>"# , "r} {}" ) ) ;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unmatched `}` in format string
|
= note: if you intended to print `}`, you can escape it using `}}`
= note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error