1
Fork 0

Auto merge of #106866 - matthiaskrgr:rollup-r063s44, r=matthiaskrgr

Rollup of 8 pull requests

Successful merges:

 - #105526 (libcore: make result of iter::from_generator Clone)
 - #106563 (Fix `unused_braces` on generic const expr macro call)
 - #106661 (Stop probing for statx unless necessary)
 - #106820 (Deprioritize fulfillment errors that come from expansions.)
 - #106828 (rustdoc: remove `docblock` class from notable trait popover)
 - #106849 (Allocate one less vec while parsing arrays)
 - #106855 (rustdoc: few small cleanups)
 - #106860 (Remove various double spaces in the libraries.)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2023-01-14 20:53:37 +00:00
commit afaf3e07aa
61 changed files with 221 additions and 161 deletions

View file

@ -1105,6 +1105,7 @@ impl UnusedDelimLint for UnusedBraces {
|| matches!(expr.kind, ast::ExprKind::Lit(_))) || matches!(expr.kind, ast::ExprKind::Lit(_)))
&& !cx.sess().source_map().is_multiline(value.span) && !cx.sess().source_map().is_multiline(value.span)
&& value.attrs.is_empty() && value.attrs.is_empty()
&& !expr.span.from_expansion()
&& !value.span.from_expansion() && !value.span.from_expansion()
&& !inner.span.from_expansion() && !inner.span.from_expansion()
{ {

View file

@ -1475,9 +1475,8 @@ impl<'a> Parser<'a> {
} else if self.eat(&token::Comma) { } else if self.eat(&token::Comma) {
// Vector with two or more elements. // Vector with two or more elements.
let sep = SeqSep::trailing_allowed(token::Comma); let sep = SeqSep::trailing_allowed(token::Comma);
let (remaining_exprs, _) = self.parse_seq_to_end(close, sep, |p| p.parse_expr())?; let (mut exprs, _) = self.parse_seq_to_end(close, sep, |p| p.parse_expr())?;
let mut exprs = vec![first_expr]; exprs.insert(0, first_expr);
exprs.extend(remaining_exprs);
ExprKind::Array(exprs) ExprKind::Array(exprs)
} else { } else {
// Vector with one element // Vector with one element

View file

@ -454,11 +454,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
} }
} }
for (error, suppressed) in iter::zip(errors, is_suppressed) { for from_expansion in [false, true] {
if !suppressed { for (error, suppressed) in iter::zip(errors, &is_suppressed) {
if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion {
self.report_fulfillment_error(error, body_id); self.report_fulfillment_error(error, body_id);
} }
} }
}
self.tcx.sess.delay_span_bug(DUMMY_SP, "expected fullfillment errors") self.tcx.sess.delay_span_bug(DUMMY_SP, "expected fullfillment errors")
} }

View file

@ -1,3 +1,4 @@
use crate::fmt;
use crate::ops::{Generator, GeneratorState}; use crate::ops::{Generator, GeneratorState};
use crate::pin::Pin; use crate::pin::Pin;
@ -23,14 +24,21 @@ use crate::pin::Pin;
/// ``` /// ```
#[inline] #[inline]
#[unstable(feature = "iter_from_generator", issue = "43122", reason = "generators are unstable")] #[unstable(feature = "iter_from_generator", issue = "43122", reason = "generators are unstable")]
pub fn from_generator<G: Generator<Return = ()> + Unpin>( pub fn from_generator<G: Generator<Return = ()> + Unpin>(generator: G) -> FromGenerator<G> {
generator: G,
) -> impl Iterator<Item = G::Yield> {
FromGenerator(generator) FromGenerator(generator)
} }
struct FromGenerator<G>(G); /// An iterator over the values yielded by an underlying generator.
///
/// This `struct` is created by the [`iter::from_generator()`] function. See its documentation for
/// more.
///
/// [`iter::from_generator()`]: from_generator
#[unstable(feature = "iter_from_generator", issue = "43122", reason = "generators are unstable")]
#[derive(Clone)]
pub struct FromGenerator<G>(G);
#[unstable(feature = "iter_from_generator", issue = "43122", reason = "generators are unstable")]
impl<G: Generator<Return = ()> + Unpin> Iterator for FromGenerator<G> { impl<G: Generator<Return = ()> + Unpin> Iterator for FromGenerator<G> {
type Item = G::Yield; type Item = G::Yield;
@ -41,3 +49,10 @@ impl<G: Generator<Return = ()> + Unpin> Iterator for FromGenerator<G> {
} }
} }
} }
#[unstable(feature = "iter_from_generator", issue = "43122", reason = "generators are unstable")]
impl<G> fmt::Debug for FromGenerator<G> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FromGenerator").finish()
}
}

View file

@ -149,12 +149,13 @@ cfg_has_statx! {{
) -> Option<io::Result<FileAttr>> { ) -> Option<io::Result<FileAttr>> {
use crate::sync::atomic::{AtomicU8, Ordering}; use crate::sync::atomic::{AtomicU8, Ordering};
// Linux kernel prior to 4.11 or glibc prior to glibc 2.28 don't support `statx` // Linux kernel prior to 4.11 or glibc prior to glibc 2.28 don't support `statx`.
// We store the availability in global to avoid unnecessary syscalls. // We check for it on first failure and remember availability to avoid having to
// 0: Unknown // do it again.
// 1: Not available #[repr(u8)]
// 2: Available enum STATX_STATE{ Unknown = 0, Present, Unavailable }
static STATX_STATE: AtomicU8 = AtomicU8::new(0); static STATX_SAVED_STATE: AtomicU8 = AtomicU8::new(STATX_STATE::Unknown as u8);
syscall! { syscall! {
fn statx( fn statx(
fd: c_int, fd: c_int,
@ -165,33 +166,46 @@ cfg_has_statx! {{
) -> c_int ) -> c_int
} }
match STATX_STATE.load(Ordering::Relaxed) { if STATX_SAVED_STATE.load(Ordering::Relaxed) == STATX_STATE::Unavailable as u8 {
0 => {
// It is a trick to call `statx` with null pointers to check if the syscall
// is available. According to the manual, it is expected to fail with EFAULT.
// We do this mainly for performance, since it is nearly hundreds times
// faster than a normal successful call.
let err = cvt(statx(0, ptr::null(), 0, libc::STATX_ALL, ptr::null_mut()))
.err()
.and_then(|e| e.raw_os_error());
// We don't check `err == Some(libc::ENOSYS)` because the syscall may be limited
// and returns `EPERM`. Listing all possible errors seems not a good idea.
// See: https://github.com/rust-lang/rust/issues/65662
if err != Some(libc::EFAULT) {
STATX_STATE.store(1, Ordering::Relaxed);
return None; return None;
} }
STATX_STATE.store(2, Ordering::Relaxed);
}
1 => return None,
_ => {}
}
let mut buf: libc::statx = mem::zeroed(); let mut buf: libc::statx = mem::zeroed();
if let Err(err) = cvt(statx(fd, path, flags, mask, &mut buf)) { if let Err(err) = cvt(statx(fd, path, flags, mask, &mut buf)) {
if STATX_SAVED_STATE.load(Ordering::Relaxed) == STATX_STATE::Present as u8 {
return Some(Err(err)); return Some(Err(err));
} }
// Availability not checked yet.
//
// First try the cheap way.
if err.raw_os_error() == Some(libc::ENOSYS) {
STATX_SAVED_STATE.store(STATX_STATE::Unavailable as u8, Ordering::Relaxed);
return None;
}
// Error other than `ENOSYS` is not a good enough indicator -- it is
// known that `EPERM` can be returned as a result of using seccomp to
// block the syscall.
// Availability is checked by performing a call which expects `EFAULT`
// if the syscall is usable.
// See: https://github.com/rust-lang/rust/issues/65662
// FIXME this can probably just do the call if `EPERM` was received, but
// previous iteration of the code checked it for all errors and for now
// this is retained.
// FIXME what about transient conditions like `ENOMEM`?
let err2 = cvt(statx(0, ptr::null(), 0, libc::STATX_ALL, ptr::null_mut()))
.err()
.and_then(|e| e.raw_os_error());
if err2 == Some(libc::EFAULT) {
STATX_SAVED_STATE.store(STATX_STATE::Present as u8, Ordering::Relaxed);
return Some(Err(err));
} else {
STATX_SAVED_STATE.store(STATX_STATE::Unavailable as u8, Ordering::Relaxed);
return None;
}
}
// We cannot fill `stat64` exhaustively because of private padding fields. // We cannot fill `stat64` exhaustively because of private padding fields.
let mut stat: stat64 = mem::zeroed(); let mut stat: stat64 = mem::zeroed();
// `c_ulong` on gnu-mips, `dev_t` otherwise // `c_ulong` on gnu-mips, `dev_t` otherwise

View file

@ -242,7 +242,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
} }
// Index this method for searching later on. // Index this method for searching later on.
if let Some(ref s) = item.name.or_else(|| { if let Some(s) = item.name.or_else(|| {
if item.is_stripped() { if item.is_stripped() {
None None
} else if let clean::ImportItem(ref i) = *item.kind && } else if let clean::ImportItem(ref i) = *item.kind &&
@ -317,14 +317,15 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
short_markdown_summary(x.as_str(), &item.link_names(self.cache)) short_markdown_summary(x.as_str(), &item.link_names(self.cache))
}); });
let ty = item.type_(); let ty = item.type_();
let name = s.to_string(); if ty != ItemType::StructField
if ty != ItemType::StructField || u16::from_str_radix(&name, 10).is_err() { || u16::from_str_radix(s.as_str(), 10).is_err()
{
// In case this is a field from a tuple struct, we don't add it into // In case this is a field from a tuple struct, we don't add it into
// the search index because its name is something like "0", which is // the search index because its name is something like "0", which is
// not useful for rustdoc search. // not useful for rustdoc search.
self.cache.search_index.push(IndexItem { self.cache.search_index.push(IndexItem {
ty, ty,
name, name: s,
path: join_with_double_colon(path), path: join_with_double_colon(path),
desc, desc,
parent, parent,

View file

@ -569,7 +569,7 @@ fn generate_macro_def_id_path(
root_path: Option<&str>, root_path: Option<&str>,
) -> Result<(String, ItemType, Vec<Symbol>), HrefError> { ) -> Result<(String, ItemType, Vec<Symbol>), HrefError> {
let tcx = cx.shared.tcx; let tcx = cx.shared.tcx;
let crate_name = tcx.crate_name(def_id.krate).to_string(); let crate_name = tcx.crate_name(def_id.krate);
let cache = cx.cache(); let cache = cx.cache();
let fqp: Vec<Symbol> = tcx let fqp: Vec<Symbol> = tcx
@ -584,7 +584,7 @@ fn generate_macro_def_id_path(
} }
}) })
.collect(); .collect();
let mut relative = fqp.iter().map(|elem| elem.to_string()); let mut relative = fqp.iter().copied();
let cstore = CStore::from_tcx(tcx); let cstore = CStore::from_tcx(tcx);
// We need this to prevent a `panic` when this function is used from intra doc links... // We need this to prevent a `panic` when this function is used from intra doc links...
if !cstore.has_crate_data(def_id.krate) { if !cstore.has_crate_data(def_id.krate) {
@ -602,9 +602,9 @@ fn generate_macro_def_id_path(
}; };
let mut path = if is_macro_2 { let mut path = if is_macro_2 {
once(crate_name.clone()).chain(relative).collect() once(crate_name).chain(relative).collect()
} else { } else {
vec![crate_name.clone(), relative.next_back().unwrap()] vec![crate_name, relative.next_back().unwrap()]
}; };
if path.len() < 2 { if path.len() < 2 {
// The minimum we can have is the crate name followed by the macro name. If shorter, then // The minimum we can have is the crate name followed by the macro name. If shorter, then
@ -614,17 +614,22 @@ fn generate_macro_def_id_path(
} }
if let Some(last) = path.last_mut() { if let Some(last) = path.last_mut() {
*last = format!("macro.{}.html", last); *last = Symbol::intern(&format!("macro.{}.html", last.as_str()));
} }
let url = match cache.extern_locations[&def_id.krate] { let url = match cache.extern_locations[&def_id.krate] {
ExternalLocation::Remote(ref s) => { ExternalLocation::Remote(ref s) => {
// `ExternalLocation::Remote` always end with a `/`. // `ExternalLocation::Remote` always end with a `/`.
format!("{}{}", s, path.join("/")) format!("{}{}", s, path.iter().map(|p| p.as_str()).join("/"))
} }
ExternalLocation::Local => { ExternalLocation::Local => {
// `root_path` always end with a `/`. // `root_path` always end with a `/`.
format!("{}{}/{}", root_path.unwrap_or(""), crate_name, path.join("/")) format!(
"{}{}/{}",
root_path.unwrap_or(""),
crate_name,
path.iter().map(|p| p.as_str()).join("/")
)
} }
ExternalLocation::Unknown => { ExternalLocation::Unknown => {
debug!("crate {} not in cache when linkifying macros", crate_name); debug!("crate {} not in cache when linkifying macros", crate_name);
@ -1050,7 +1055,7 @@ fn fmt_type<'cx>(
_ => String::new(), _ => String::new(),
}; };
let m = mutability.print_with_space(); let m = mutability.print_with_space();
let amp = if f.alternate() { "&".to_string() } else { "&amp;".to_string() }; let amp = if f.alternate() { "&" } else { "&amp;" };
match **ty { match **ty {
clean::DynTrait(ref bounds, ref trait_lt) clean::DynTrait(ref bounds, ref trait_lt)
if bounds.len() > 1 || trait_lt.is_some() => if bounds.len() > 1 || trait_lt.is_some() =>

View file

@ -30,7 +30,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::HirId; use rustc_hir::HirId;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_span::edition::Edition; use rustc_span::edition::Edition;
use rustc_span::Span; use rustc_span::{Span, Symbol};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::borrow::Cow; use std::borrow::Cow;
@ -198,7 +198,7 @@ fn slugify(c: char) -> Option<char> {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Playground { pub struct Playground {
pub crate_name: Option<String>, pub crate_name: Option<Symbol>,
pub url: String, pub url: String,
} }
@ -290,7 +290,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
.map(|l| map_line(l).for_code()) .map(|l| map_line(l).for_code())
.intersperse("\n".into()) .intersperse("\n".into())
.collect::<String>(); .collect::<String>();
let krate = krate.as_ref().map(|s| &**s); let krate = krate.as_ref().map(|s| s.as_str());
let (test, _, _) = let (test, _, _) =
doctest::make_test(&test, krate, false, &Default::default(), edition, None); doctest::make_test(&test, krate, false, &Default::default(), edition, None);
let channel = if test.contains("#![feature(") { "&amp;version=nightly" } else { "" }; let channel = if test.contains("#![feature(") { "&amp;version=nightly" } else { "" };

View file

@ -464,8 +464,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
// If user passed in `--playground-url` arg, we fill in crate name here // If user passed in `--playground-url` arg, we fill in crate name here
let mut playground = None; let mut playground = None;
if let Some(url) = playground_url { if let Some(url) = playground_url {
playground = playground = Some(markdown::Playground { crate_name: Some(krate.name(tcx)), url });
Some(markdown::Playground { crate_name: Some(krate.name(tcx).to_string()), url });
} }
let mut layout = layout::Layout { let mut layout = layout::Layout {
logo: String::new(), logo: String::new(),
@ -491,7 +490,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
} }
(sym::html_playground_url, Some(s)) => { (sym::html_playground_url, Some(s)) => {
playground = Some(markdown::Playground { playground = Some(markdown::Playground {
crate_name: Some(krate.name(tcx).to_string()), crate_name: Some(krate.name(tcx)),
url: s.to_string(), url: s.to_string(),
}); });
} }

View file

@ -100,7 +100,7 @@ pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct IndexItem { pub(crate) struct IndexItem {
pub(crate) ty: ItemType, pub(crate) ty: ItemType,
pub(crate) name: String, pub(crate) name: Symbol,
pub(crate) path: String, pub(crate) path: String,
pub(crate) desc: String, pub(crate) desc: String,
pub(crate) parent: Option<DefId>, pub(crate) parent: Option<DefId>,
@ -1343,7 +1343,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
write!( write!(
&mut out, &mut out,
"<h3>Notable traits for <code>{}</code></h3>\ "<h3>Notable traits for <code>{}</code></h3>\
<pre class=\"content\"><code>", <pre><code>",
impl_.for_.print(cx) impl_.for_.print(cx)
); );
} }
@ -2769,8 +2769,8 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
let mut work = VecDeque::new(); let mut work = VecDeque::new();
let mut process_path = |did: DefId| { let mut process_path = |did: DefId| {
let get_extern = || cache.external_paths.get(&did).map(|s| s.0.clone()); let get_extern = || cache.external_paths.get(&did).map(|s| &s.0);
let fqp = cache.exact_paths.get(&did).cloned().or_else(get_extern); let fqp = cache.exact_paths.get(&did).or_else(get_extern);
if let Some(path) = fqp { if let Some(path) = fqp {
out.push(join_with_double_colon(&path)); out.push(join_with_double_colon(&path));

View file

@ -1027,8 +1027,8 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
.chain(std::iter::once("implementors")) .chain(std::iter::once("implementors"))
.collect(); .collect();
if let Some(did) = it.item_id.as_def_id() && if let Some(did) = it.item_id.as_def_id() &&
let get_extern = { || cache.external_paths.get(&did).map(|s| s.0.clone()) } && let get_extern = { || cache.external_paths.get(&did).map(|s| &s.0) } &&
let Some(fqp) = cache.exact_paths.get(&did).cloned().or_else(get_extern) { let Some(fqp) = cache.exact_paths.get(&did).or_else(get_extern) {
js_src_path.extend(fqp[..fqp.len() - 1].iter().copied()); js_src_path.extend(fqp[..fqp.len() - 1].iter().copied());
js_src_path.push_fmt(format_args!("{}.{}.js", it.type_(), fqp.last().unwrap())); js_src_path.push_fmt(format_args!("{}.{}.js", it.type_(), fqp.last().unwrap()));
} else { } else {

View file

@ -35,7 +35,7 @@ pub(crate) fn build_index<'tcx>(
.map_or_else(String::new, |s| short_markdown_summary(&s, &item.link_names(cache))); .map_or_else(String::new, |s| short_markdown_summary(&s, &item.link_names(cache)));
cache.search_index.push(IndexItem { cache.search_index.push(IndexItem {
ty: item.type_(), ty: item.type_(),
name: item.name.unwrap().to_string(), name: item.name.unwrap(),
path: join_with_double_colon(&fqp[..fqp.len() - 1]), path: join_with_double_colon(&fqp[..fqp.len() - 1]),
desc, desc,
parent: Some(parent), parent: Some(parent),
@ -58,8 +58,8 @@ pub(crate) fn build_index<'tcx>(
// Sort search index items. This improves the compressibility of the search index. // Sort search index items. This improves the compressibility of the search index.
cache.search_index.sort_unstable_by(|k1, k2| { cache.search_index.sort_unstable_by(|k1, k2| {
// `sort_unstable_by_key` produces lifetime errors // `sort_unstable_by_key` produces lifetime errors
let k1 = (&k1.path, &k1.name, &k1.ty, &k1.parent); let k1 = (&k1.path, k1.name.as_str(), &k1.ty, &k1.parent);
let k2 = (&k2.path, &k2.name, &k2.ty, &k2.parent); let k2 = (&k2.path, k2.name.as_str(), &k2.ty, &k2.parent);
std::cmp::Ord::cmp(&k1, &k2) std::cmp::Ord::cmp(&k1, &k2)
}); });
@ -240,7 +240,7 @@ pub(crate) fn build_index<'tcx>(
)?; )?;
crate_data.serialize_field( crate_data.serialize_field(
"n", "n",
&self.items.iter().map(|item| &item.name).collect::<Vec<_>>(), &self.items.iter().map(|item| item.name.as_str()).collect::<Vec<_>>(),
)?; )?;
crate_data.serialize_field( crate_data.serialize_field(
"q", "q",
@ -299,7 +299,7 @@ pub(crate) fn build_index<'tcx>(
)?; )?;
crate_data.serialize_field( crate_data.serialize_field(
"p", "p",
&self.paths.iter().map(|(it, s)| (it, s.to_string())).collect::<Vec<_>>(), &self.paths.iter().map(|(it, s)| (it, s.as_str())).collect::<Vec<_>>(),
)?; )?;
if has_aliases { if has_aliases {
crate_data.serialize_field("a", &self.aliases)?; crate_data.serialize_field("a", &self.aliases)?;

View file

@ -1214,11 +1214,11 @@ a.test-arrow:hover {
content: "\00a0"; content: "\00a0";
} }
.notable .docblock { .notable .content {
margin: 0.25em 0.5em; margin: 0.25em 0.5em;
} }
.notable .docblock pre, .notable .docblock code { .notable .content pre, .notable .content code {
background: transparent; background: transparent;
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -1226,6 +1226,10 @@ a.test-arrow:hover {
white-space: pre-wrap; white-space: pre-wrap;
} }
.notable .content > h3:first-child {
margin: 0 0 5px 0;
}
.search-failed { .search-failed {
text-align: center; text-align: center;
margin-top: 20px; margin-top: 20px;

View file

@ -847,7 +847,7 @@ function loadCss(cssUrl) {
window.hideAllModals(false); window.hideAllModals(false);
const ty = e.getAttribute("data-ty"); const ty = e.getAttribute("data-ty");
const wrapper = document.createElement("div"); const wrapper = document.createElement("div");
wrapper.innerHTML = "<div class=\"docblock\">" + window.NOTABLE_TRAITS[ty] + "</div>"; wrapper.innerHTML = "<div class=\"content\">" + window.NOTABLE_TRAITS[ty] + "</div>";
wrapper.className = "notable popover"; wrapper.className = "notable popover";
const focusCatcher = document.createElement("div"); const focusCatcher = document.createElement("div");
focusCatcher.setAttribute("tabindex", "0"); focusCatcher.setAttribute("tabindex", "0");

View file

@ -22,7 +22,8 @@ fn main() {
} }
// test `stat` // test `stat`
assert_eq!(fs::metadata("foo.txt").unwrap_err().kind(), ErrorKind::PermissionDenied); let err = fs::metadata("foo.txt").unwrap_err();
assert_eq!(err.kind(), ErrorKind::PermissionDenied);
// check that it is the right kind of `PermissionDenied` // check that it is the right kind of `PermissionDenied`
assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EACCES)); assert_eq!(err.raw_os_error(), Some(libc::EACCES));
} }

View file

@ -1 +1 @@
<script type="text/json" id="notable-traits-data">{"&amp;'static [SomeStruct]":"&lt;h3&gt;Notable traits for &lt;code&gt;&amp;amp;[&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\"&gt;SomeStruct&lt;/a&gt;]&lt;/code&gt;&lt;/h3&gt;&lt;pre class=\"content\"&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait_slice::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &amp;amp;[&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\"&gt;SomeStruct&lt;/a&gt;]&lt;/span&gt;"}</script> <script type="text/json" id="notable-traits-data">{"&amp;'static [SomeStruct]":"&lt;h3&gt;Notable traits for &lt;code&gt;&amp;amp;[&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\"&gt;SomeStruct&lt;/a&gt;]&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait_slice::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &amp;amp;[&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\"&gt;SomeStruct&lt;/a&gt;]&lt;/span&gt;"}</script>

View file

@ -1 +1 @@
<script type="text/json" id="notable-traits-data">{"SomeStruct":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre class=\"content\"&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/span&gt;"}</script> <script type="text/json" id="notable-traits-data">{"SomeStruct":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/span&gt;"}</script>

View file

@ -1 +1 @@
<script type="text/json" id="notable-traits-data">{"SomeStruct":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre class=\"content\"&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/span&gt;","Wrapper&lt;Self&gt;":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre class=\"content\"&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl&amp;lt;T:&amp;nbsp;&lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt;&amp;gt; &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/span&gt;"}</script> <script type="text/json" id="notable-traits-data">{"SomeStruct":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/span&gt;","Wrapper&lt;Self&gt;":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl&amp;lt;T:&amp;nbsp;&lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt;&amp;gt; &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/span&gt;"}</script>

View file

@ -1 +1 @@
<script type="text/json" id="notable-traits-data">{"Wrapper&lt;Self&gt;":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre class=\"content\"&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl&amp;lt;T:&amp;nbsp;&lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt;&amp;gt; &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/span&gt;"}</script> <script type="text/json" id="notable-traits-data">{"Wrapper&lt;Self&gt;":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl&amp;lt;T:&amp;nbsp;&lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt;&amp;gt; &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/span&gt;"}</script>

View file

@ -1 +1 @@
<script type="text/json" id="notable-traits-data">{"Odd":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\"&gt;Odd&lt;/a&gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre class=\"content\"&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl &lt;a class=\"trait\" href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html\" title=\"trait core::iter::traits::iterator::Iterator\"&gt;Iterator&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\"&gt;Odd&lt;/a&gt;&lt;/span&gt;&lt;span class=\"where fmt-newline\"&gt; type &lt;a href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html#associatedtype.Item\" class=\"associatedtype\"&gt;Item&lt;/a&gt; = &lt;a class=\"primitive\" href=\"{{channel}}/std/primitive.usize.html\"&gt;usize&lt;/a&gt;;&lt;/span&gt;"}</script> <script type="text/json" id="notable-traits-data">{"Odd":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\"&gt;Odd&lt;/a&gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl &lt;a class=\"trait\" href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html\" title=\"trait core::iter::traits::iterator::Iterator\"&gt;Iterator&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\"&gt;Odd&lt;/a&gt;&lt;/span&gt;&lt;span class=\"where fmt-newline\"&gt; type &lt;a href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html#associatedtype.Item\" class=\"associatedtype\"&gt;Item&lt;/a&gt; = &lt;a class=\"primitive\" href=\"{{channel}}/std/primitive.usize.html\"&gt;usize&lt;/a&gt;;&lt;/span&gt;"}</script>

View file

@ -2,10 +2,17 @@
// run-rustfix // run-rustfix
#![warn(unused_braces)] #![warn(unused_braces)]
macro_rules! make_1 {
() => {
1
}
}
struct A<const N: usize>; struct A<const N: usize>;
fn main() { fn main() {
let _: A<7>; // ok let _: A<7>; // ok
let _: A<7>; //~ WARN unnecessary braces let _: A<7>; //~ WARN unnecessary braces
let _: A<{ 3 + 5 }>; // ok let _: A<{ 3 + 5 }>; // ok
let _: A<{make_1!()}>; // ok
} }

View file

@ -2,10 +2,17 @@
// run-rustfix // run-rustfix
#![warn(unused_braces)] #![warn(unused_braces)]
macro_rules! make_1 {
() => {
1
}
}
struct A<const N: usize>; struct A<const N: usize>;
fn main() { fn main() {
let _: A<7>; // ok let _: A<7>; // ok
let _: A<{ 7 }>; //~ WARN unnecessary braces let _: A<{ 7 }>; //~ WARN unnecessary braces
let _: A<{ 3 + 5 }>; // ok let _: A<{ 3 + 5 }>; // ok
let _: A<{make_1!()}>; // ok
} }

View file

@ -1,5 +1,5 @@
warning: unnecessary braces around const expression warning: unnecessary braces around const expression
--> $DIR/unused_braces.rs:9:14 --> $DIR/unused_braces.rs:15:14
| |
LL | let _: A<{ 7 }>; LL | let _: A<{ 7 }>;
| ^^ ^^ | ^^ ^^

View file

@ -1,8 +1,6 @@
error[E0282]: type annotations needed error[E0282]: type annotations needed
--> $DIR/cannot-infer-partial-try-return.rs:20:9 --> $DIR/cannot-infer-partial-try-return.rs:20:9
| |
LL | infallible()?;
| ------------- type must be known at this point
LL | Ok(()) LL | Ok(())
| ^^ cannot infer type of the type parameter `E` declared on the enum `Result` | ^^ cannot infer type of the type parameter `E` declared on the enum `Result`
| |

View file

@ -1,8 +1,13 @@
error[E0282]: type annotations needed error[E0282]: type annotations needed
--> $DIR/question-mark-type-infer.rs:10:30 --> $DIR/question-mark-type-infer.rs:10:21
| |
LL | l.iter().map(f).collect()? LL | l.iter().map(f).collect()?
| ^ cannot infer type | ^^^^^^^ cannot infer type of the type parameter `B` declared on the associated function `collect`
|
help: consider specifying the generic argument
|
LL | l.iter().map(f).collect::<Vec<_>>()?
| ++++++++++
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,13 +1,15 @@
error[E0282]: type annotations needed error[E0284]: type annotations needed
--> $DIR/issue-69455.rs:29:20 --> $DIR/issue-69455.rs:29:41
| |
LL | println!("{}", 23u64.test(xs.iter().sum())); LL | println!("{}", 23u64.test(xs.iter().sum()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the associated function `new_display` | ---- ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum`
| |
| type must be known at this point
| |
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) = note: cannot satisfy `<u64 as Test<_>>::Output == _`
help: consider specifying the generic argument help: consider specifying the generic argument
| |
LL | println!("{}", 23u64.test(xs.iter().sum())::<T>); LL | println!("{}", 23u64.test(xs.iter().sum::<S>()));
| +++++ | +++++
error[E0283]: type annotations needed error[E0283]: type annotations needed
@ -33,5 +35,5 @@ LL | println!("{}", 23u64.test(xs.iter().sum::<S>()));
error: aborting due to 2 previous errors error: aborting due to 2 previous errors
Some errors have detailed explanations: E0282, E0283. Some errors have detailed explanations: E0283, E0284.
For more information about an error, try `rustc --explain E0282`. For more information about an error, try `rustc --explain E0283`.

View file

@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `(Vec<T>,)`
--> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:9 --> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:9
| |
LL | let (x, ) = (vec![], ); LL | let (x, ) = (vec![], );
| ^^^^^ | ^^^^^ ---------- type must be known at this point
| |
help: consider giving this pattern a type, where the type for type parameter `T` is specified help: consider giving this pattern a type, where the type for type parameter `T` is specified
| |