Auto merge of #76804 - tmandry:rollup-nwntt3q, r=tmandry

Rollup of 16 pull requests

Successful merges:

 - #75026 (Add array_windows fn)
 - #76642 (Do not lint ignored private doc tests)
 - #76719 (Change error message for ty param in const)
 - #76721 (Use intra-doc links in `core::mem`)
 - #76728 (Add a comment why `extern crate` is necessary for rustdoc)
 - #76735 (Remove unnecessary `clone()`s in bootstrap)
 - #76741 (Avoid printing dry run timings)
 - #76747 (Add missing code examples in libcore)
 - #76756 (fix a couple of stylistic clippy warnings)
 - #76758 ([fuchsia] Propagate the userspace UTC clock)
 - #76759 (Fix stabilization marker for future_readiness_fns)
 - #76760 (don't lazily evaluate some trivial values for Option::None replacements (clippy::unnecessary_lazy_evaluations))
 - #76764 (Update books)
 - #76775 (Strip a single leading tab when rendering dataflow diffs)
 - #76778 (Simplify iter fuse struct doc)
 - #76794 (Make graphviz font configurable)

Failed merges:

r? `@ghost`
This commit is contained in:
bors 2020-09-16 20:18:19 +00:00
commit 285fc7d704
54 changed files with 450 additions and 164 deletions

View file

@ -591,14 +591,14 @@ pub trait GraphWalk<'a> {
fn target(&'a self, edge: &Self::Edge) -> Self::Node; fn target(&'a self, edge: &Self::Edge) -> Self::Node;
} }
#[derive(Copy, Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug)]
pub enum RenderOption { pub enum RenderOption {
NoEdgeLabels, NoEdgeLabels,
NoNodeLabels, NoNodeLabels,
NoEdgeStyles, NoEdgeStyles,
NoNodeStyles, NoNodeStyles,
Monospace, Fontname(String),
DarkTheme, DarkTheme,
} }
@ -633,11 +633,14 @@ where
// Global graph properties // Global graph properties
let mut graph_attrs = Vec::new(); let mut graph_attrs = Vec::new();
let mut content_attrs = Vec::new(); let mut content_attrs = Vec::new();
if options.contains(&RenderOption::Monospace) { let font;
let font = r#"fontname="Courier, monospace""#; if let Some(fontname) = options.iter().find_map(|option| {
graph_attrs.push(font); if let RenderOption::Fontname(fontname) = option { Some(fontname) } else { None }
content_attrs.push(font); }) {
}; font = format!(r#"fontname="{}""#, fontname);
graph_attrs.push(&font[..]);
content_attrs.push(&font[..]);
}
if options.contains(&RenderOption::DarkTheme) { if options.contains(&RenderOption::DarkTheme) {
graph_attrs.push(r#"bgcolor="black""#); graph_attrs.push(r#"bgcolor="black""#);
content_attrs.push(r#"color="white""#); content_attrs.push(r#"color="white""#);

View file

@ -85,7 +85,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
debug!("try_report_named_anon_conflict: ret ty {:?}", ty); debug!("try_report_named_anon_conflict: ret ty {:?}", ty);
if sub == &ty::ReStatic if sub == &ty::ReStatic
&& v.0.into_iter().find(|t| t.span.desugaring_kind().is_none()).is_some() && v.0.into_iter().any(|t| t.span.desugaring_kind().is_none())
{ {
// If the failure is due to a `'static` requirement coming from a `dyn` or // If the failure is due to a `'static` requirement coming from a `dyn` or
// `impl` Trait that *isn't* caused by `async fn` desugaring, handle this case // `impl` Trait that *isn't* caused by `async fn` desugaring, handle this case

View file

@ -961,7 +961,7 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: &
continue; continue;
} }
let span = sugared_span.take().unwrap_or_else(|| attr.span); let span = sugared_span.take().unwrap_or(attr.span);
if attr.is_doc_comment() || cx.sess().check_name(attr, sym::doc) { if attr.is_doc_comment() || cx.sess().check_name(attr, sym::doc) {
cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, |lint| { cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, |lint| {

View file

@ -170,7 +170,7 @@ impl Collector<'tcx> {
feature_err( feature_err(
&self.tcx.sess.parse_sess, &self.tcx.sess.parse_sess,
sym::static_nobundle, sym::static_nobundle,
span.unwrap_or_else(|| rustc_span::DUMMY_SP), span.unwrap_or(rustc_span::DUMMY_SP),
"kind=\"static-nobundle\" is unstable", "kind=\"static-nobundle\" is unstable",
) )
.emit(); .emit();
@ -179,7 +179,7 @@ impl Collector<'tcx> {
feature_err( feature_err(
&self.tcx.sess.parse_sess, &self.tcx.sess.parse_sess,
sym::raw_dylib, sym::raw_dylib,
span.unwrap_or_else(|| rustc_span::DUMMY_SP), span.unwrap_or(rustc_span::DUMMY_SP),
"kind=\"raw-dylib\" is unstable", "kind=\"raw-dylib\" is unstable",
) )
.emit(); .emit();

View file

@ -273,10 +273,10 @@ pub trait PrettyPrinter<'tcx>:
} }
match self.tcx().trimmed_def_paths(LOCAL_CRATE).get(&def_id) { match self.tcx().trimmed_def_paths(LOCAL_CRATE).get(&def_id) {
None => return Ok((self, false)), None => Ok((self, false)),
Some(symbol) => { Some(symbol) => {
self.write_str(&symbol.as_str())?; self.write_str(&symbol.as_str())?;
return Ok((self, true)); Ok((self, true))
} }
} }
} }

View file

@ -387,7 +387,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if let ReturnConstraint::ClosureUpvar(upvar) = kind { if let ReturnConstraint::ClosureUpvar(upvar) = kind {
let def_id = match self.regioncx.universal_regions().defining_ty { let def_id = match self.regioncx.universal_regions().defining_ty {
DefiningTy::Closure(def_id, _) => def_id, DefiningTy::Closure(def_id, _) => def_id,
ty @ _ => bug!("unexpected DefiningTy {:?}", ty), ty => bug!("unexpected DefiningTy {:?}", ty),
}; };
let upvar_def_span = self.infcx.tcx.hir().span(upvar); let upvar_def_span = self.infcx.tcx.hir().span(upvar);

View file

@ -306,7 +306,8 @@ where
let mut buf = Vec::new(); let mut buf = Vec::new();
let graphviz = graphviz::Formatter::new(body, def_id, results, style); let graphviz = graphviz::Formatter::new(body, def_id, results, style);
let mut render_opts = vec![dot::RenderOption::Monospace]; let mut render_opts =
vec![dot::RenderOption::Fontname(tcx.sess.opts.debugging_opts.graphviz_font.clone())];
if tcx.sess.opts.debugging_opts.graphviz_dark_mode { if tcx.sess.opts.debugging_opts.graphviz_dark_mode {
render_opts.push(dot::RenderOption::DarkTheme); render_opts.push(dot::RenderOption::DarkTheme);
} }

View file

@ -578,7 +578,7 @@ where
return String::new(); return String::new();
} }
let re = Regex::new("\u{001f}([+-])").unwrap(); let re = Regex::new("\t?\u{001f}([+-])").unwrap();
let raw_diff = format!("{:#?}", DebugDiffWithAdapter { new, old, ctxt }); let raw_diff = format!("{:#?}", DebugDiffWithAdapter { new, old, ctxt });

View file

@ -126,7 +126,7 @@ impl OptimizationFinder<'b, 'tcx> {
} }
} }
return None; None
} }
} }

View file

@ -55,9 +55,9 @@ where
writeln!(w, "{} {}Mir_{} {{", kind, cluster, def_name)?; writeln!(w, "{} {}Mir_{} {{", kind, cluster, def_name)?;
// Global graph properties // Global graph properties
let font = r#"fontname="Courier, monospace""#; let font = format!(r#"fontname="{}""#, tcx.sess.opts.debugging_opts.graphviz_font);
let mut graph_attrs = vec![font]; let mut graph_attrs = vec![&font[..]];
let mut content_attrs = vec![font]; let mut content_attrs = vec![&font[..]];
let dark_mode = tcx.sess.opts.debugging_opts.graphviz_dark_mode; let dark_mode = tcx.sess.opts.debugging_opts.graphviz_dark_mode;
if dark_mode { if dark_mode {

View file

@ -466,7 +466,7 @@ impl<'a> Resolver<'a> {
); );
err err
} }
ResolutionError::ParamInNonTrivialAnonConst(name) => { ResolutionError::ParamInNonTrivialAnonConst { name, is_type } => {
let mut err = self.session.struct_span_err( let mut err = self.session.struct_span_err(
span, span,
"generic parameters must not be used inside of non trivial constant values", "generic parameters must not be used inside of non trivial constant values",
@ -478,9 +478,17 @@ impl<'a> Resolver<'a> {
name name
), ),
); );
err.help(
&format!("it is currently only allowed to use either `{0}` or `{{ {0} }}` as generic constants", name) if is_type {
); err.note("type parameters are currently not permitted in anonymous constants");
} else {
err.help(
&format!("it is currently only allowed to use either `{0}` or `{{ {0} }}` as generic constants",
name
)
);
}
err err
} }
ResolutionError::SelfInTyParamDefault => { ResolutionError::SelfInTyParamDefault => {

View file

@ -1534,7 +1534,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
} }
}; };
let lifetime_names: Vec<_> = lifetime_names.into_iter().collect(); let lifetime_names: Vec<_> = lifetime_names.iter().collect();
match (&lifetime_names[..], snippet.as_deref()) { match (&lifetime_names[..], snippet.as_deref()) {
([name], Some("&")) => { ([name], Some("&")) => {
suggest_existing(err, &name.as_str()[..], &|name| format!("&{} ", name)); suggest_existing(err, &name.as_str()[..], &|name| format!("&{} ", name));

View file

@ -221,7 +221,7 @@ enum ResolutionError<'a> {
/// generic parameters must not be used inside of non trivial constant values. /// generic parameters must not be used inside of non trivial constant values.
/// ///
/// This error is only emitted when using `min_const_generics`. /// This error is only emitted when using `min_const_generics`.
ParamInNonTrivialAnonConst(Symbol), ParamInNonTrivialAnonConst { name: Symbol, is_type: bool },
/// Error E0735: type parameters with a default cannot use `Self` /// Error E0735: type parameters with a default cannot use `Self`
SelfInTyParamDefault, SelfInTyParamDefault,
/// Error E0767: use of unreachable label /// Error E0767: use of unreachable label
@ -2638,9 +2638,10 @@ impl<'a> Resolver<'a> {
if record_used { if record_used {
self.report_error( self.report_error(
span, span,
ResolutionError::ParamInNonTrivialAnonConst( ResolutionError::ParamInNonTrivialAnonConst {
rib_ident.name, name: rib_ident.name,
), is_type: true,
},
); );
} }
return Res::Err; return Res::Err;
@ -2718,7 +2719,10 @@ impl<'a> Resolver<'a> {
if record_used { if record_used {
self.report_error( self.report_error(
span, span,
ResolutionError::ParamInNonTrivialAnonConst(rib_ident.name), ResolutionError::ParamInNonTrivialAnonConst {
name: rib_ident.name,
is_type: false,
},
); );
} }
return Res::Err; return Res::Err;

View file

@ -1762,6 +1762,10 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
debugging_opts.symbol_mangling_version = SymbolManglingVersion::V0; debugging_opts.symbol_mangling_version = SymbolManglingVersion::V0;
} }
if let Ok(graphviz_font) = std::env::var("RUSTC_GRAPHVIZ_FONT") {
debugging_opts.graphviz_font = graphviz_font;
}
if !cg.embed_bitcode { if !cg.embed_bitcode {
match cg.lto { match cg.lto {
LtoCli::No | LtoCli::Unspecified => {} LtoCli::No | LtoCli::Unspecified => {}

View file

@ -911,6 +911,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"set the optimization fuel quota for a crate"), "set the optimization fuel quota for a crate"),
graphviz_dark_mode: bool = (false, parse_bool, [UNTRACKED], graphviz_dark_mode: bool = (false, parse_bool, [UNTRACKED],
"use dark-themed colors in graphviz output (default: no)"), "use dark-themed colors in graphviz output (default: no)"),
graphviz_font: String = ("Courier, monospace".to_string(), parse_string, [UNTRACKED],
"use the given `fontname` in graphviz output; can be overridden by setting \
environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)"),
hir_stats: bool = (false, parse_bool, [UNTRACKED], hir_stats: bool = (false, parse_bool, [UNTRACKED],
"print some statistics about AST and HIR (default: no)"), "print some statistics about AST and HIR (default: no)"),
human_readable_cgu_names: bool = (false, parse_bool, [TRACKED], human_readable_cgu_names: bool = (false, parse_bool, [TRACKED],

View file

@ -182,7 +182,7 @@ fn overlap_within_probe(
} }
if !skip_leak_check.is_yes() { if !skip_leak_check.is_yes() {
if let Err(_) = infcx.leak_check(true, snapshot) { if infcx.leak_check(true, snapshot).is_err() {
debug!("overlap: leak check failed"); debug!("overlap: leak check failed");
return None; return None;
} }

View file

@ -164,7 +164,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
// If all the obligations hold (or there are no obligations) the tail expression // If all the obligations hold (or there are no obligations) the tail expression
// we can suggest to return a boxed trait object instead of an opaque type. // we can suggest to return a boxed trait object instead of an opaque type.
if suggest_box { self.ret_type_span.clone() } else { None } if suggest_box { self.ret_type_span } else { None }
} }
_ => None, _ => None,
}; };

View file

@ -1243,10 +1243,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else if check_completeness && !error_happened && !remaining_fields.is_empty() { } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
let no_accessible_remaining_fields = remaining_fields let no_accessible_remaining_fields = remaining_fields
.iter() .iter()
.filter(|(_, (_, field))| { .find(|(_, (_, field))| {
field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx) field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx)
}) })
.next()
.is_none(); .is_none();
if no_accessible_remaining_fields { if no_accessible_remaining_fields {

View file

@ -1141,10 +1141,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else if !etc && !unmentioned_fields.is_empty() { } else if !etc && !unmentioned_fields.is_empty() {
let no_accessible_unmentioned_fields = unmentioned_fields let no_accessible_unmentioned_fields = unmentioned_fields
.iter() .iter()
.filter(|(field, _)| { .find(|(field, _)| {
field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx) field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx)
}) })
.next()
.is_none(); .is_none();
if no_accessible_unmentioned_fields { if no_accessible_unmentioned_fields {

View file

@ -76,6 +76,7 @@
#![cfg_attr(test, feature(test))] #![cfg_attr(test, feature(test))]
#![feature(allocator_api)] #![feature(allocator_api)]
#![feature(array_chunks)] #![feature(array_chunks)]
#![feature(array_windows)]
#![feature(allow_internal_unstable)] #![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)] #![feature(arbitrary_self_types)]
#![feature(box_patterns)] #![feature(box_patterns)]

View file

@ -97,6 +97,8 @@ pub use core::slice::check_range;
pub use core::slice::ArrayChunks; pub use core::slice::ArrayChunks;
#[unstable(feature = "array_chunks", issue = "74985")] #[unstable(feature = "array_chunks", issue = "74985")]
pub use core::slice::ArrayChunksMut; pub use core::slice::ArrayChunksMut;
#[unstable(feature = "array_windows", issue = "75027")]
pub use core::slice::ArrayWindows;
#[stable(feature = "slice_get_slice", since = "1.28.0")] #[stable(feature = "slice_get_slice", since = "1.28.0")]
pub use core::slice::SliceIndex; pub use core::slice::SliceIndex;
#[stable(feature = "from_ref", since = "1.28.0")] #[stable(feature = "from_ref", since = "1.28.0")]

View file

@ -21,9 +21,9 @@ pub use self::future::Future;
#[unstable(feature = "into_future", issue = "67644")] #[unstable(feature = "into_future", issue = "67644")]
pub use into_future::IntoFuture; pub use into_future::IntoFuture;
#[stable(feature = "future_readiness_fns", since = "1.47.0")] #[stable(feature = "future_readiness_fns", since = "1.48.0")]
pub use pending::{pending, Pending}; pub use pending::{pending, Pending};
#[stable(feature = "future_readiness_fns", since = "1.47.0")] #[stable(feature = "future_readiness_fns", since = "1.48.0")]
pub use ready::{ready, Ready}; pub use ready::{ready, Ready};
#[unstable(feature = "future_poll_fn", issue = "72302")] #[unstable(feature = "future_poll_fn", issue = "72302")]

View file

@ -11,7 +11,7 @@ use crate::task::{Context, Poll};
/// documentation for more. /// documentation for more.
/// ///
/// [`pending`]: fn.pending.html /// [`pending`]: fn.pending.html
#[stable(feature = "future_readiness_fns", since = "1.47.0")] #[stable(feature = "future_readiness_fns", since = "1.48.0")]
#[must_use = "futures do nothing unless you `.await` or poll them"] #[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Pending<T> { pub struct Pending<T> {
_data: marker::PhantomData<T>, _data: marker::PhantomData<T>,
@ -31,12 +31,12 @@ pub struct Pending<T> {
/// unreachable!(); /// unreachable!();
/// # } /// # }
/// ``` /// ```
#[stable(feature = "future_readiness_fns", since = "1.47.0")] #[stable(feature = "future_readiness_fns", since = "1.48.0")]
pub fn pending<T>() -> Pending<T> { pub fn pending<T>() -> Pending<T> {
Pending { _data: marker::PhantomData } Pending { _data: marker::PhantomData }
} }
#[stable(feature = "future_readiness_fns", since = "1.47.0")] #[stable(feature = "future_readiness_fns", since = "1.48.0")]
impl<T> Future for Pending<T> { impl<T> Future for Pending<T> {
type Output = T; type Output = T;
@ -45,17 +45,17 @@ impl<T> Future for Pending<T> {
} }
} }
#[stable(feature = "future_readiness_fns", since = "1.47.0")] #[stable(feature = "future_readiness_fns", since = "1.48.0")]
impl<T> Unpin for Pending<T> {} impl<T> Unpin for Pending<T> {}
#[stable(feature = "future_readiness_fns", since = "1.47.0")] #[stable(feature = "future_readiness_fns", since = "1.48.0")]
impl<T> Debug for Pending<T> { impl<T> Debug for Pending<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Pending").finish() f.debug_struct("Pending").finish()
} }
} }
#[stable(feature = "future_readiness_fns", since = "1.47.0")] #[stable(feature = "future_readiness_fns", since = "1.48.0")]
impl<T> Clone for Pending<T> { impl<T> Clone for Pending<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
pending() pending()

View file

@ -8,15 +8,15 @@ use crate::task::{Context, Poll};
/// documentation for more. /// documentation for more.
/// ///
/// [`ready`]: fn.ready.html /// [`ready`]: fn.ready.html
#[stable(feature = "future_readiness_fns", since = "1.47.0")] #[stable(feature = "future_readiness_fns", since = "1.48.0")]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[must_use = "futures do nothing unless you `.await` or poll them"] #[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Ready<T>(Option<T>); pub struct Ready<T>(Option<T>);
#[stable(feature = "future_readiness_fns", since = "1.47.0")] #[stable(feature = "future_readiness_fns", since = "1.48.0")]
impl<T> Unpin for Ready<T> {} impl<T> Unpin for Ready<T> {}
#[stable(feature = "future_readiness_fns", since = "1.47.0")] #[stable(feature = "future_readiness_fns", since = "1.48.0")]
impl<T> Future for Ready<T> { impl<T> Future for Ready<T> {
type Output = T; type Output = T;
@ -42,7 +42,7 @@ impl<T> Future for Ready<T> {
/// assert_eq!(a.await, 1); /// assert_eq!(a.await, 1);
/// # } /// # }
/// ``` /// ```
#[stable(feature = "future_readiness_fns", since = "1.47.0")] #[stable(feature = "future_readiness_fns", since = "1.48.0")]
pub fn ready<T>(t: T) -> Ready<T> { pub fn ready<T>(t: T) -> Ready<T> {
Ready(Some(t)) Ready(Some(t))
} }

View file

@ -9,11 +9,8 @@ use crate::ops::Try;
/// An iterator that yields `None` forever after the underlying iterator /// An iterator that yields `None` forever after the underlying iterator
/// yields `None` once. /// yields `None` once.
/// ///
/// This `struct` is created by the [`fuse`] method on [`Iterator`]. See its /// This `struct` is created by [`Iterator::fuse`]. See its documentation
/// documentation for more. /// for more.
///
/// [`fuse`]: trait.Iterator.html#method.fuse
/// [`Iterator`]: trait.Iterator.html
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"] #[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]

View file

@ -31,10 +31,10 @@ pub use crate::intrinsics::transmute;
/// forever in an unreachable state. However, it does not guarantee that pointers /// forever in an unreachable state. However, it does not guarantee that pointers
/// to this memory will remain valid. /// to this memory will remain valid.
/// ///
/// * If you want to leak memory, see [`Box::leak`][leak]. /// * If you want to leak memory, see [`Box::leak`].
/// * If you want to obtain a raw pointer to the memory, see [`Box::into_raw`][into_raw]. /// * If you want to obtain a raw pointer to the memory, see [`Box::into_raw`].
/// * If you want to dispose of a value properly, running its destructor, see /// * If you want to dispose of a value properly, running its destructor, see
/// [`mem::drop`][drop]. /// [`mem::drop`].
/// ///
/// # Safety /// # Safety
/// ///
@ -132,15 +132,11 @@ pub use crate::intrinsics::transmute;
/// ownership to `s` — the final step of interacting with `v` to dispose of it without /// ownership to `s` — the final step of interacting with `v` to dispose of it without
/// running its destructor is entirely avoided. /// running its destructor is entirely avoided.
/// ///
/// [drop]: fn.drop.html /// [`Box`]: ../../std/boxed/struct.Box.html
/// [uninit]: fn.uninitialized.html /// [`Box::leak`]: ../../std/boxed/struct.Box.html#method.leak
/// [clone]: ../clone/trait.Clone.html /// [`Box::into_raw`]: ../../std/boxed/struct.Box.html#method.into_raw
/// [swap]: fn.swap.html /// [`mem::drop`]: drop
/// [box]: ../../std/boxed/struct.Box.html
/// [leak]: ../../std/boxed/struct.Box.html#method.leak
/// [into_raw]: ../../std/boxed/struct.Box.html#method.into_raw
/// [ub]: ../../reference/behavior-considered-undefined.html /// [ub]: ../../reference/behavior-considered-undefined.html
/// [`ManuallyDrop`]: struct.ManuallyDrop.html
#[inline] #[inline]
#[rustc_const_stable(feature = "const_forget", since = "1.46.0")] #[rustc_const_stable(feature = "const_forget", since = "1.46.0")]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -152,8 +148,6 @@ pub const fn forget<T>(t: T) {
/// ///
/// This function is just a shim intended to be removed when the `unsized_locals` feature gets /// This function is just a shim intended to be removed when the `unsized_locals` feature gets
/// stabilized. /// stabilized.
///
/// [`forget`]: fn.forget.html
#[inline] #[inline]
#[unstable(feature = "forget_unsized", issue = "none")] #[unstable(feature = "forget_unsized", issue = "none")]
pub fn forget_unsized<T: ?Sized>(t: T) { pub fn forget_unsized<T: ?Sized>(t: T) {
@ -301,7 +295,7 @@ pub fn forget_unsized<T: ?Sized>(t: T) {
/// assert_eq!(2, mem::size_of::<ExampleUnion>()); /// assert_eq!(2, mem::size_of::<ExampleUnion>());
/// ``` /// ```
/// ///
/// [alignment]: ./fn.align_of.html /// [alignment]: align_of
#[inline(always)] #[inline(always)]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_promotable] #[rustc_promotable]
@ -365,7 +359,6 @@ pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
/// [slice]: ../../std/primitive.slice.html /// [slice]: ../../std/primitive.slice.html
/// [trait object]: ../../book/ch17-02-trait-objects.html /// [trait object]: ../../book/ch17-02-trait-objects.html
/// [extern type]: ../../unstable-book/language-features/extern-types.html /// [extern type]: ../../unstable-book/language-features/extern-types.html
/// [`size_of_val`]: ../../core/mem/fn.size_of_val.html
/// ///
/// # Examples /// # Examples
/// ///
@ -501,7 +494,6 @@ pub const fn align_of_val<T: ?Sized>(val: &T) -> usize {
/// [slice]: ../../std/primitive.slice.html /// [slice]: ../../std/primitive.slice.html
/// [trait object]: ../../book/ch17-02-trait-objects.html /// [trait object]: ../../book/ch17-02-trait-objects.html
/// [extern type]: ../../unstable-book/language-features/extern-types.html /// [extern type]: ../../unstable-book/language-features/extern-types.html
/// [`align_of_val`]: ../../core/mem/fn.align_of_val.html
/// ///
/// # Examples /// # Examples
/// ///
@ -540,7 +532,7 @@ pub unsafe fn align_of_val_raw<T: ?Sized>(val: *const T) -> usize {
/// `needs_drop` explicitly. Types like [`HashMap`], on the other hand, have to drop /// `needs_drop` explicitly. Types like [`HashMap`], on the other hand, have to drop
/// values one at a time and should use this API. /// values one at a time and should use this API.
/// ///
/// [`drop_in_place`]: ../ptr/fn.drop_in_place.html /// [`drop_in_place`]: crate::ptr::drop_in_place
/// [`HashMap`]: ../../std/collections/struct.HashMap.html /// [`HashMap`]: ../../std/collections/struct.HashMap.html
/// ///
/// # Examples /// # Examples
@ -595,9 +587,9 @@ pub const fn needs_drop<T>() -> bool {
/// This has the same effect as [`MaybeUninit::zeroed().assume_init()`][zeroed]. /// This has the same effect as [`MaybeUninit::zeroed().assume_init()`][zeroed].
/// It is useful for FFI sometimes, but should generally be avoided. /// It is useful for FFI sometimes, but should generally be avoided.
/// ///
/// [zeroed]: union.MaybeUninit.html#method.zeroed /// [zeroed]: MaybeUninit::zeroed
/// [ub]: ../../reference/behavior-considered-undefined.html /// [ub]: ../../reference/behavior-considered-undefined.html
/// [inv]: union.MaybeUninit.html#initialization-invariant /// [inv]: MaybeUninit#initialization-invariant
/// ///
/// # Examples /// # Examples
/// ///
@ -650,10 +642,10 @@ pub unsafe fn zeroed<T>() -> T {
/// (Notice that the rules around uninitialized integers are not finalized yet, but /// (Notice that the rules around uninitialized integers are not finalized yet, but
/// until they are, it is advisable to avoid them.) /// until they are, it is advisable to avoid them.)
/// ///
/// [`MaybeUninit<T>`]: union.MaybeUninit.html /// [`MaybeUninit<T>`]: MaybeUninit
/// [uninit]: union.MaybeUninit.html#method.uninit /// [uninit]: MaybeUninit::uninit
/// [assume_init]: union.MaybeUninit.html#method.assume_init /// [assume_init]: MaybeUninit::assume_init
/// [inv]: union.MaybeUninit.html#initialization-invariant /// [inv]: MaybeUninit#initialization-invariant
#[inline(always)] #[inline(always)]
#[rustc_deprecated(since = "1.39.0", reason = "use `mem::MaybeUninit` instead")] #[rustc_deprecated(since = "1.39.0", reason = "use `mem::MaybeUninit` instead")]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -686,9 +678,6 @@ pub unsafe fn uninitialized<T>() -> T {
/// assert_eq!(42, x); /// assert_eq!(42, x);
/// assert_eq!(5, y); /// assert_eq!(5, y);
/// ``` /// ```
///
/// [`replace`]: fn.replace.html
/// [`take`]: fn.take.html
#[inline] #[inline]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn swap<T>(x: &mut T, y: &mut T) { pub fn swap<T>(x: &mut T, y: &mut T) {
@ -754,10 +743,6 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
/// assert_eq!(buffer.get_and_reset(), vec![0, 1]); /// assert_eq!(buffer.get_and_reset(), vec![0, 1]);
/// assert_eq!(buffer.buf.len(), 0); /// assert_eq!(buffer.buf.len(), 0);
/// ``` /// ```
///
/// [`Clone`]: ../../std/clone/trait.Clone.html
/// [`replace`]: fn.replace.html
/// [`swap`]: fn.swap.html
#[inline] #[inline]
#[stable(feature = "mem_take", since = "1.40.0")] #[stable(feature = "mem_take", since = "1.40.0")]
pub fn take<T: Default>(dest: &mut T) -> T { pub fn take<T: Default>(dest: &mut T) -> T {
@ -822,10 +807,6 @@ pub fn take<T: Default>(dest: &mut T) -> T {
/// assert_eq!(buffer.replace_index(0, 2), 0); /// assert_eq!(buffer.replace_index(0, 2), 0);
/// assert_eq!(buffer.buf[0], 2); /// assert_eq!(buffer.buf[0], 2);
/// ``` /// ```
///
/// [`Clone`]: ../../std/clone/trait.Clone.html
/// [`swap`]: fn.swap.html
/// [`take`]: fn.take.html
#[inline] #[inline]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "if you don't need the old value, you can just assign the new value directly"] #[must_use = "if you don't need the old value, you can just assign the new value directly"]
@ -851,7 +832,7 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
/// Because `_x` is moved into the function, it is automatically dropped before /// Because `_x` is moved into the function, it is automatically dropped before
/// the function returns. /// the function returns.
/// ///
/// [drop]: ../ops/trait.Drop.html /// [drop]: Drop
/// ///
/// # Examples /// # Examples
/// ///
@ -894,8 +875,7 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
/// println!("x: {}, y: {}", x, y.0); // still available /// println!("x: {}, y: {}", x, y.0); // still available
/// ``` /// ```
/// ///
/// [`RefCell`]: ../../std/cell/struct.RefCell.html /// [`RefCell`]: crate::cell::RefCell
/// [`Copy`]: ../../std/marker/trait.Copy.html
#[inline] #[inline]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn drop<T>(_x: T) {} pub fn drop<T>(_x: T) {}
@ -914,7 +894,6 @@ pub fn drop<T>(_x: T) {}
/// `T`. /// `T`.
/// ///
/// [ub]: ../../reference/behavior-considered-undefined.html /// [ub]: ../../reference/behavior-considered-undefined.html
/// [size_of]: fn.size_of.html
/// ///
/// # Examples /// # Examples
/// ///
@ -960,8 +939,6 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
/// Opaque type representing the discriminant of an enum. /// Opaque type representing the discriminant of an enum.
/// ///
/// See the [`discriminant`] function in this module for more information. /// See the [`discriminant`] function in this module for more information.
///
/// [`discriminant`]: fn.discriminant.html
#[stable(feature = "discriminant_value", since = "1.21.0")] #[stable(feature = "discriminant_value", since = "1.21.0")]
pub struct Discriminant<T>(<T as DiscriminantKind>::Discriminant); pub struct Discriminant<T>(<T as DiscriminantKind>::Discriminant);

View file

@ -166,6 +166,16 @@ from_str_float_impl!(f64);
/// ///
/// This error is used as the error type for the [`FromStr`] implementation /// This error is used as the error type for the [`FromStr`] implementation
/// for [`f32`] and [`f64`]. /// for [`f32`] and [`f64`].
///
/// # Example
///
/// ```
/// use std::str::FromStr;
///
/// if let Err(e) = f64::from_str("a.12") {
/// println!("Failed conversion to f64: {}", e);
/// }
/// ```
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct ParseFloatError { pub struct ParseFloatError {

View file

@ -5286,6 +5286,14 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) -> Result<T, Par
/// ///
/// [`str.trim()`]: ../../std/primitive.str.html#method.trim /// [`str.trim()`]: ../../std/primitive.str.html#method.trim
/// [`i8::from_str_radix`]: ../../std/primitive.i8.html#method.from_str_radix /// [`i8::from_str_radix`]: ../../std/primitive.i8.html#method.from_str_radix
///
/// # Example
///
/// ```
/// if let Err(e) = i32::from_str_radix("a12", 10) {
/// println!("Failed conversion to i32: {}", e);
/// }
/// ```
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct ParseIntError { pub struct ParseIntError {
@ -5293,6 +5301,18 @@ pub struct ParseIntError {
} }
/// Enum to store the various types of errors that can cause parsing an integer to fail. /// Enum to store the various types of errors that can cause parsing an integer to fail.
///
/// # Example
///
/// ```
/// #![feature(int_error_matching)]
///
/// # fn main() {
/// if let Err(e) = i32::from_str_radix("a12", 10) {
/// println!("Failed conversion to i32: {:?}", e.kind());
/// }
/// # }
/// ```
#[unstable( #[unstable(
feature = "int_error_matching", feature = "int_error_matching",
reason = "it can be useful to match errors when making error messages \ reason = "it can be useful to match errors when making error messages \

View file

@ -1687,6 +1687,106 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
} }
} }
/// A windowed iterator over a slice in overlapping chunks (`N` elements at a
/// time), starting at the beginning of the slice
///
/// This struct is created by the [`array_windows`] method on [slices].
///
/// [`array_windows`]: ../../std/primitive.slice.html#method.array_windows
/// [slices]: ../../std/primitive.slice.html
#[derive(Debug, Clone, Copy)]
#[unstable(feature = "array_windows", issue = "75027")]
pub struct ArrayWindows<'a, T: 'a, const N: usize> {
pub(crate) slice_head: *const T,
pub(crate) num: usize,
pub(crate) marker: marker::PhantomData<&'a [T; N]>,
}
#[unstable(feature = "array_windows", issue = "75027")]
impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> {
type Item = &'a [T; N];
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.num == 0 {
return None;
}
// SAFETY:
// This is safe because it's indexing into a slice guaranteed to be length > N.
let ret = unsafe { &*self.slice_head.cast::<[T; N]>() };
// SAFETY: Guaranteed that there are at least 1 item remaining otherwise
// earlier branch would've been hit
self.slice_head = unsafe { self.slice_head.add(1) };
self.num -= 1;
Some(ret)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.num, Some(self.num))
}
#[inline]
fn count(self) -> usize {
self.num
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
if self.num <= n {
self.num = 0;
return None;
}
// SAFETY:
// This is safe because it's indexing into a slice guaranteed to be length > N.
let ret = unsafe { &*self.slice_head.add(n).cast::<[T; N]>() };
// SAFETY: Guaranteed that there are at least n items remaining
self.slice_head = unsafe { self.slice_head.add(n + 1) };
self.num -= n + 1;
Some(ret)
}
#[inline]
fn last(mut self) -> Option<Self::Item> {
self.nth(self.num.checked_sub(1)?)
}
}
#[unstable(feature = "array_windows", issue = "75027")]
impl<'a, T, const N: usize> DoubleEndedIterator for ArrayWindows<'a, T, N> {
#[inline]
fn next_back(&mut self) -> Option<&'a [T; N]> {
if self.num == 0 {
return None;
}
// SAFETY: Guaranteed that there are n items remaining, n-1 for 0-indexing.
let ret = unsafe { &*self.slice_head.add(self.num - 1).cast::<[T; N]>() };
self.num -= 1;
Some(ret)
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<&'a [T; N]> {
if self.num <= n {
self.num = 0;
return None;
}
// SAFETY: Guaranteed that there are n items remaining, n-1 for 0-indexing.
let ret = unsafe { &*self.slice_head.add(self.num - (n + 1)).cast::<[T; N]>() };
self.num -= n + 1;
Some(ret)
}
}
#[unstable(feature = "array_windows", issue = "75027")]
impl<T, const N: usize> ExactSizeIterator for ArrayWindows<'_, T, N> {
fn is_empty(&self) -> bool {
self.num == 0
}
}
/// An iterator over a slice in (non-overlapping) chunks (`N` elements at a /// An iterator over a slice in (non-overlapping) chunks (`N` elements at a
/// time), starting at the beginning of the slice. /// time), starting at the beginning of the slice.
/// ///

View file

@ -56,6 +56,9 @@ pub use iter::{RChunks, RChunksExact, RChunksExactMut, RChunksMut};
#[unstable(feature = "array_chunks", issue = "74985")] #[unstable(feature = "array_chunks", issue = "74985")]
pub use iter::{ArrayChunks, ArrayChunksMut}; pub use iter::{ArrayChunks, ArrayChunksMut};
#[unstable(feature = "array_windows", issue = "75027")]
pub use iter::ArrayWindows;
#[unstable(feature = "split_inclusive", issue = "72360")] #[unstable(feature = "split_inclusive", issue = "72360")]
pub use iter::{SplitInclusive, SplitInclusiveMut}; pub use iter::{SplitInclusive, SplitInclusiveMut};
@ -1026,6 +1029,40 @@ impl<T> [T] {
} }
} }
/// Returns an iterator over overlapping windows of `N` elements of a slice,
/// starting at the beginning of the slice.
///
/// This is the const generic equivalent of [`windows`].
///
/// If `N` is smaller than the size of the array, it will return no windows.
///
/// # Panics
///
/// Panics if `N` is 0. This check will most probably get changed to a compile time
/// error before this method gets stabilized.
///
/// # Examples
///
/// ```
/// #![feature(array_windows)]
/// let slice = [0, 1, 2, 3];
/// let mut iter = slice.array_windows();
/// assert_eq!(iter.next().unwrap(), &[0, 1]);
/// assert_eq!(iter.next().unwrap(), &[1, 2]);
/// assert_eq!(iter.next().unwrap(), &[2, 3]);
/// assert!(iter.next().is_none());
/// ```
///
/// [`windows`]: #method.windows
#[unstable(feature = "array_windows", issue = "75027")]
#[inline]
pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> {
assert_ne!(N, 0);
let num_windows = self.len().saturating_sub(N - 1);
ArrayWindows { slice_head: self.as_ptr(), num: num_windows, marker: marker::PhantomData }
}
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
/// of the slice. /// of the slice.
/// ///

View file

@ -2,6 +2,7 @@
#![feature(array_chunks)] #![feature(array_chunks)]
#![feature(array_methods)] #![feature(array_methods)]
#![feature(array_map)] #![feature(array_map)]
#![feature(array_windows)]
#![feature(bool_to_option)] #![feature(bool_to_option)]
#![feature(bound_cloned)] #![feature(bound_cloned)]
#![feature(box_syntax)] #![feature(box_syntax)]

View file

@ -657,6 +657,55 @@ fn test_array_chunks_mut_zip() {
assert_eq!(v1, [13, 14, 19, 20, 4]); assert_eq!(v1, [13, 14, 19, 20, 4]);
} }
#[test]
fn test_array_windows_infer() {
let v: &[i32] = &[0, 1, 0, 1];
assert_eq!(v.array_windows::<2>().count(), 3);
let c = v.array_windows();
for &[a, b] in c {
assert_eq!(a + b, 1);
}
let v2: &[i32] = &[0, 1, 2, 3, 4, 5, 6];
let total = v2.array_windows().map(|&[a, b, c]| a + b + c).sum::<i32>();
assert_eq!(total, 3 + 6 + 9 + 12 + 15);
}
#[test]
fn test_array_windows_count() {
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
let c = v.array_windows::<3>();
assert_eq!(c.count(), 4);
let v2: &[i32] = &[0, 1, 2, 3, 4];
let c2 = v2.array_windows::<6>();
assert_eq!(c2.count(), 0);
let v3: &[i32] = &[];
let c3 = v3.array_windows::<2>();
assert_eq!(c3.count(), 0);
}
#[test]
fn test_array_windows_nth() {
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
let snd = v.array_windows::<4>().nth(1);
assert_eq!(snd, Some(&[1, 2, 3, 4]));
let mut arr_windows = v.array_windows::<2>();
assert_ne!(arr_windows.nth(0), arr_windows.nth(0));
let last = v.array_windows::<3>().last();
assert_eq!(last, Some(&[3, 4, 5]));
}
#[test]
fn test_array_windows_nth_back() {
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
let snd = v.array_windows::<4>().nth_back(1);
assert_eq!(snd, Some(&[1, 2, 3, 4]));
let mut arr_windows = v.array_windows::<2>();
assert_ne!(arr_windows.nth_back(0), arr_windows.nth_back(0));
}
#[test] #[test]
fn test_rchunks_count() { fn test_rchunks_count() {
let v: &[i32] = &[0, 1, 2, 3, 4, 5]; let v: &[i32] = &[0, 1, 2, 3, 4, 5];

View file

@ -9,7 +9,7 @@ pub use core::future::Future;
pub use core::future::{from_generator, get_context, ResumeTy}; pub use core::future::{from_generator, get_context, ResumeTy};
#[doc(inline)] #[doc(inline)]
#[stable(feature = "future_readiness_fns", since = "1.47.0")] #[stable(feature = "future_readiness_fns", since = "1.48.0")]
pub use core::future::{pending, ready, Pending, Ready}; pub use core::future::{pending, ready, Pending, Ready};
#[doc(inline)] #[doc(inline)]

View file

@ -118,7 +118,8 @@ impl Command {
FDIO_SPAWN_CLONE_JOB FDIO_SPAWN_CLONE_JOB
| FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_LDSVC
| FDIO_SPAWN_CLONE_NAMESPACE | FDIO_SPAWN_CLONE_NAMESPACE
| FDIO_SPAWN_CLONE_ENVIRON, // this is ignored when envp is non-null | FDIO_SPAWN_CLONE_ENVIRON // this is ignored when envp is non-null
| FDIO_SPAWN_CLONE_UTC_CLOCK,
self.get_program().as_ptr(), self.get_program().as_ptr(),
self.get_argv().as_ptr(), self.get_argv().as_ptr(),
envp, envp,

View file

@ -138,6 +138,7 @@ pub const FDIO_SPAWN_CLONE_LDSVC: u32 = 0x0002;
pub const FDIO_SPAWN_CLONE_NAMESPACE: u32 = 0x0004; pub const FDIO_SPAWN_CLONE_NAMESPACE: u32 = 0x0004;
pub const FDIO_SPAWN_CLONE_STDIO: u32 = 0x0008; pub const FDIO_SPAWN_CLONE_STDIO: u32 = 0x0008;
pub const FDIO_SPAWN_CLONE_ENVIRON: u32 = 0x0010; pub const FDIO_SPAWN_CLONE_ENVIRON: u32 = 0x0010;
pub const FDIO_SPAWN_CLONE_UTC_CLOCK: u32 = 0x0020;
pub const FDIO_SPAWN_CLONE_ALL: u32 = 0xFFFF; pub const FDIO_SPAWN_CLONE_ALL: u32 = 0xFFFF;
// fdio_spawn_etc actions // fdio_spawn_etc actions

View file

@ -1209,7 +1209,7 @@ impl<'a> Builder<'a> {
cargo.env(format!("CC_{}", target.triple), &cc); cargo.env(format!("CC_{}", target.triple), &cc);
let cflags = self.cflags(target, GitRepo::Rustc).join(" "); let cflags = self.cflags(target, GitRepo::Rustc).join(" ");
cargo.env(format!("CFLAGS_{}", target.triple), cflags.clone()); cargo.env(format!("CFLAGS_{}", target.triple), &cflags);
if let Some(ar) = self.ar(target) { if let Some(ar) = self.ar(target) {
let ranlib = format!("{} s", ar.display()); let ranlib = format!("{} s", ar.display());
@ -1394,7 +1394,7 @@ impl<'a> Builder<'a> {
(out, dur - deps) (out, dur - deps)
}; };
if self.config.print_step_timings { if self.config.print_step_timings && !self.config.dry_run {
println!("[TIMING] {:?} -- {}.{:03}", step, dur.as_secs(), dur.subsec_millis()); println!("[TIMING] {:?} -- {}.{:03}", step, dur.as_secs(), dur.subsec_millis());
} }

View file

@ -500,6 +500,7 @@ impl Config {
pub fn parse(args: &[String]) -> Config { pub fn parse(args: &[String]) -> Config {
let flags = Flags::parse(&args); let flags = Flags::parse(&args);
let mut config = Config::default_opts(); let mut config = Config::default_opts();
config.exclude = flags.exclude; config.exclude = flags.exclude;
config.rustc_error_format = flags.rustc_error_format; config.rustc_error_format = flags.rustc_error_format;
@ -551,14 +552,14 @@ impl Config {
let has_targets = build.target.is_some() || flags.target.is_some(); let has_targets = build.target.is_some() || flags.target.is_some();
config.skip_only_host_steps = !has_hosts && has_targets; config.skip_only_host_steps = !has_hosts && has_targets;
config.hosts = if let Some(arg_host) = flags.host.clone() { config.hosts = if let Some(arg_host) = flags.host {
arg_host arg_host
} else if let Some(file_host) = build.host { } else if let Some(file_host) = build.host {
file_host.iter().map(|h| TargetSelection::from_user(h)).collect() file_host.iter().map(|h| TargetSelection::from_user(h)).collect()
} else { } else {
vec![config.build] vec![config.build]
}; };
config.targets = if let Some(arg_target) = flags.target.clone() { config.targets = if let Some(arg_target) = flags.target {
arg_target arg_target
} else if let Some(file_target) = build.target { } else if let Some(file_target) = build.target {
file_target.iter().map(|h| TargetSelection::from_user(h)).collect() file_target.iter().map(|h| TargetSelection::from_user(h)).collect()
@ -628,14 +629,14 @@ impl Config {
config.verbose = cmp::max(config.verbose, flags.verbose); config.verbose = cmp::max(config.verbose, flags.verbose);
if let Some(ref install) = toml.install { if let Some(install) = toml.install {
config.prefix = install.prefix.clone().map(PathBuf::from); config.prefix = install.prefix.map(PathBuf::from);
config.sysconfdir = install.sysconfdir.clone().map(PathBuf::from); config.sysconfdir = install.sysconfdir.map(PathBuf::from);
config.datadir = install.datadir.clone().map(PathBuf::from); config.datadir = install.datadir.map(PathBuf::from);
config.docdir = install.docdir.clone().map(PathBuf::from); config.docdir = install.docdir.map(PathBuf::from);
set(&mut config.bindir, install.bindir.clone().map(PathBuf::from)); set(&mut config.bindir, install.bindir.map(PathBuf::from));
config.libdir = install.libdir.clone().map(PathBuf::from); config.libdir = install.libdir.map(PathBuf::from);
config.mandir = install.mandir.clone().map(PathBuf::from); config.mandir = install.mandir.map(PathBuf::from);
} }
// We want the llvm-skip-rebuild flag to take precedence over the // We want the llvm-skip-rebuild flag to take precedence over the
@ -658,7 +659,7 @@ impl Config {
let mut optimize = None; let mut optimize = None;
let mut ignore_git = None; let mut ignore_git = None;
if let Some(ref llvm) = toml.llvm { if let Some(llvm) = toml.llvm {
match llvm.ccache { match llvm.ccache {
Some(StringOrBool::String(ref s)) => config.ccache = Some(s.to_string()), Some(StringOrBool::String(ref s)) => config.ccache = Some(s.to_string()),
Some(StringOrBool::Bool(true)) => { Some(StringOrBool::Bool(true)) => {
@ -726,7 +727,7 @@ impl Config {
} }
} }
if let Some(ref rust) = toml.rust { if let Some(rust) = toml.rust {
debug = rust.debug; debug = rust.debug;
debug_assertions = rust.debug_assertions; debug_assertions = rust.debug_assertions;
debug_assertions_std = rust.debug_assertions_std; debug_assertions_std = rust.debug_assertions_std;
@ -746,7 +747,7 @@ impl Config {
set(&mut config.test_compare_mode, rust.test_compare_mode); set(&mut config.test_compare_mode, rust.test_compare_mode);
set(&mut config.llvm_libunwind, rust.llvm_libunwind); set(&mut config.llvm_libunwind, rust.llvm_libunwind);
set(&mut config.backtrace, rust.backtrace); set(&mut config.backtrace, rust.backtrace);
set(&mut config.channel, rust.channel.clone()); set(&mut config.channel, rust.channel);
set(&mut config.rust_dist_src, rust.dist_src); set(&mut config.rust_dist_src, rust.dist_src);
set(&mut config.verbose_tests, rust.verbose_tests); set(&mut config.verbose_tests, rust.verbose_tests);
// in the case "false" is set explicitly, do not overwrite the command line args // in the case "false" is set explicitly, do not overwrite the command line args
@ -757,9 +758,9 @@ impl Config {
set(&mut config.lld_enabled, rust.lld); set(&mut config.lld_enabled, rust.lld);
set(&mut config.llvm_tools_enabled, rust.llvm_tools); set(&mut config.llvm_tools_enabled, rust.llvm_tools);
config.rustc_parallel = rust.parallel_compiler.unwrap_or(false); config.rustc_parallel = rust.parallel_compiler.unwrap_or(false);
config.rustc_default_linker = rust.default_linker.clone(); config.rustc_default_linker = rust.default_linker;
config.musl_root = rust.musl_root.clone().map(PathBuf::from); config.musl_root = rust.musl_root.map(PathBuf::from);
config.save_toolstates = rust.save_toolstates.clone().map(PathBuf::from); config.save_toolstates = rust.save_toolstates.map(PathBuf::from);
set(&mut config.deny_warnings, flags.deny_warnings.or(rust.deny_warnings)); set(&mut config.deny_warnings, flags.deny_warnings.or(rust.deny_warnings));
set(&mut config.backtrace_on_ice, rust.backtrace_on_ice); set(&mut config.backtrace_on_ice, rust.backtrace_on_ice);
set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir); set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir);
@ -776,9 +777,9 @@ impl Config {
config.rust_codegen_units_std = rust.codegen_units_std.map(threads_from_config); config.rust_codegen_units_std = rust.codegen_units_std.map(threads_from_config);
} }
if let Some(ref t) = toml.target { if let Some(t) = toml.target {
for (triple, cfg) in t { for (triple, cfg) in t {
let mut target = Target::from_triple(triple); let mut target = Target::from_triple(&triple);
if let Some(ref s) = cfg.llvm_config { if let Some(ref s) = cfg.llvm_config {
target.llvm_config = Some(config.src.join(s)); target.llvm_config = Some(config.src.join(s));
@ -792,18 +793,18 @@ impl Config {
if let Some(s) = cfg.no_std { if let Some(s) = cfg.no_std {
target.no_std = s; target.no_std = s;
} }
target.cc = cfg.cc.clone().map(PathBuf::from); target.cc = cfg.cc.map(PathBuf::from);
target.cxx = cfg.cxx.clone().map(PathBuf::from); target.cxx = cfg.cxx.map(PathBuf::from);
target.ar = cfg.ar.clone().map(PathBuf::from); target.ar = cfg.ar.map(PathBuf::from);
target.ranlib = cfg.ranlib.clone().map(PathBuf::from); target.ranlib = cfg.ranlib.map(PathBuf::from);
target.linker = cfg.linker.clone().map(PathBuf::from); target.linker = cfg.linker.map(PathBuf::from);
target.crt_static = cfg.crt_static; target.crt_static = cfg.crt_static;
target.musl_root = cfg.musl_root.clone().map(PathBuf::from); target.musl_root = cfg.musl_root.map(PathBuf::from);
target.musl_libdir = cfg.musl_libdir.clone().map(PathBuf::from); target.musl_libdir = cfg.musl_libdir.map(PathBuf::from);
target.wasi_root = cfg.wasi_root.clone().map(PathBuf::from); target.wasi_root = cfg.wasi_root.map(PathBuf::from);
target.qemu_rootfs = cfg.qemu_rootfs.clone().map(PathBuf::from); target.qemu_rootfs = cfg.qemu_rootfs.map(PathBuf::from);
config.target_config.insert(TargetSelection::from_user(triple), target); config.target_config.insert(TargetSelection::from_user(&triple), target);
} }
} }
@ -821,10 +822,10 @@ impl Config {
build_target.llvm_filecheck = Some(ci_llvm_bin.join(exe("FileCheck", config.build))); build_target.llvm_filecheck = Some(ci_llvm_bin.join(exe("FileCheck", config.build)));
} }
if let Some(ref t) = toml.dist { if let Some(t) = toml.dist {
config.dist_sign_folder = t.sign_folder.clone().map(PathBuf::from); config.dist_sign_folder = t.sign_folder.map(PathBuf::from);
config.dist_gpg_password_file = t.gpg_password_file.clone().map(PathBuf::from); config.dist_gpg_password_file = t.gpg_password_file.map(PathBuf::from);
config.dist_upload_addr = t.upload_addr.clone(); config.dist_upload_addr = t.upload_addr;
set(&mut config.rust_dist_src, t.src_tarball); set(&mut config.rust_dist_src, t.src_tarball);
set(&mut config.missing_tools, t.missing_tools); set(&mut config.missing_tools, t.missing_tools);
} }

View file

@ -105,15 +105,13 @@ pub fn format(build: &Build, check: bool) {
eprintln!("./x.py fmt is not supported on this channel"); eprintln!("./x.py fmt is not supported on this channel");
std::process::exit(1); std::process::exit(1);
}); });
let src = build.src.clone(); let src = &build.src;
let walker = WalkBuilder::new(&build.src).types(matcher).overrides(ignore_fmt).build_parallel(); let walker = WalkBuilder::new(src).types(matcher).overrides(ignore_fmt).build_parallel();
walker.run(|| { walker.run(|| {
let src = src.clone();
let rustfmt_path = rustfmt_path.clone();
Box::new(move |entry| { Box::new(move |entry| {
let entry = t!(entry); let entry = t!(entry);
if entry.file_type().map_or(false, |t| t.is_file()) { if entry.file_type().map_or(false, |t| t.is_file()) {
rustfmt(&src, &rustfmt_path, &entry.path(), check); rustfmt(src, &rustfmt_path, &entry.path(), check);
} }
ignore::WalkState::Continue ignore::WalkState::Continue
}) })

View file

@ -30,8 +30,8 @@ impl Finder {
Self { cache: HashMap::new(), path: env::var_os("PATH").unwrap_or_default() } Self { cache: HashMap::new(), path: env::var_os("PATH").unwrap_or_default() }
} }
pub fn maybe_have<S: AsRef<OsStr>>(&mut self, cmd: S) -> Option<PathBuf> { pub fn maybe_have<S: Into<OsString>>(&mut self, cmd: S) -> Option<PathBuf> {
let cmd: OsString = cmd.as_ref().into(); let cmd: OsString = cmd.into();
let path = &self.path; let path = &self.path;
self.cache self.cache
.entry(cmd.clone()) .entry(cmd.clone())

@ -1 +1 @@
Subproject commit e5ed97128302d5fa45dbac0e64426bc7649a558c Subproject commit cb28dee95e5e50b793e6ba9291c5d1568d3ad72e

@ -1 +1 @@
Subproject commit 25854752549d44d76fbd7650e17cb4f167a0b8fb Subproject commit 6e57e64501f61873ab80cb78a07180a22751a5d6

@ -1 +1 @@
Subproject commit 25391dba46262f882fa846beefaff54a966a8fa5 Subproject commit 56a13c082ee90736c08d6abdcd90462517b703d3

View file

@ -16,6 +16,16 @@
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
#[macro_use]
extern crate tracing;
// N.B. these need `extern crate` even in 2018 edition
// because they're loaded implicitly from the sysroot.
// The reason they're loaded from the sysroot is because
// the rustdoc artifacts aren't stored in rustc's cargo target directory.
// So if `rustc` was specified in Cargo.toml, this would spuriously rebuild crates.
//
// Dependencies listed in Cargo.toml do not need `extern crate`.
extern crate rustc_ast; extern crate rustc_ast;
extern crate rustc_ast_pretty; extern crate rustc_ast_pretty;
extern crate rustc_attr; extern crate rustc_attr;
@ -42,8 +52,6 @@ extern crate rustc_target;
extern crate rustc_trait_selection; extern crate rustc_trait_selection;
extern crate rustc_typeck; extern crate rustc_typeck;
extern crate test as testing; extern crate test as testing;
#[macro_use]
extern crate tracing;
use std::default::Default; use std::default::Default;
use std::env; use std::env;

View file

@ -8,7 +8,7 @@ use crate::clean;
use crate::clean::*; use crate::clean::*;
use crate::core::DocContext; use crate::core::DocContext;
use crate::fold::DocFolder; use crate::fold::DocFolder;
use crate::html::markdown::{find_testable_code, ErrorCodes, LangString}; use crate::html::markdown::{find_testable_code, ErrorCodes, Ignore, LangString};
use rustc_session::lint; use rustc_session::lint;
pub const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = Pass { pub const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = Pass {
@ -48,15 +48,11 @@ pub(crate) struct Tests {
pub(crate) found_tests: usize, pub(crate) found_tests: usize,
} }
impl Tests {
pub(crate) fn new() -> Tests {
Tests { found_tests: 0 }
}
}
impl crate::doctest::Tester for Tests { impl crate::doctest::Tester for Tests {
fn add_test(&mut self, _: String, _: LangString, _: usize) { fn add_test(&mut self, _: String, config: LangString, _: usize) {
self.found_tests += 1; if config.rust && config.ignore == Ignore::None {
self.found_tests += 1;
}
} }
} }
@ -85,7 +81,7 @@ pub fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) {
} }
}; };
let mut tests = Tests::new(); let mut tests = Tests { found_tests: 0 };
find_testable_code(&dox, &mut tests, ErrorCodes::No, false, None); find_testable_code(&dox, &mut tests, ErrorCodes::No, false, None);

View file

@ -1,7 +1,7 @@
+-------------------------------------+------------+------------+------------+------------+ +-------------------------------------+------------+------------+------------+------------+
| File | Documented | Percentage | Examples | Percentage | | File | Documented | Percentage | Examples | Percentage |
+-------------------------------------+------------+------------+------------+------------+ +-------------------------------------+------------+------------+------------+------------+
| ...tdoc-ui/coverage/doc-examples.rs | 4 | 100.0% | 2 | 50.0% | | ...tdoc-ui/coverage/doc-examples.rs | 4 | 100.0% | 1 | 25.0% |
+-------------------------------------+------------+------------+------------+------------+ +-------------------------------------+------------+------------+------------+------------+
| Total | 4 | 100.0% | 2 | 50.0% | | Total | 4 | 100.0% | 1 | 25.0% |
+-------------------------------------+------------+------------+------------+------------+ +-------------------------------------+------------+------------+------------+------------+

View file

@ -0,0 +1,12 @@
// check-pass
#![deny(private_doc_tests)]
mod foo {
/// private doc test
///
/// ```ignore (used for testing ignored doc tests)
/// assert!(false);
/// ```
fn bar() {}
}

View file

@ -4,7 +4,7 @@ error: generic parameters must not be used inside of non trivial constant values
LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {} LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {}
| ^^^^^^ non-trivial anonymous constants must not depend on the parameter `T` | ^^^^^^ non-trivial anonymous constants must not depend on the parameter `T`
| |
= help: it is currently only allowed to use either `T` or `{ T }` as generic constants = note: type parameters are currently not permitted in anonymous constants
error: generic parameters must not be used inside of non trivial constant values error: generic parameters must not be used inside of non trivial constant values
--> $DIR/issue-64494.rs:19:38 --> $DIR/issue-64494.rs:19:38
@ -12,7 +12,7 @@ error: generic parameters must not be used inside of non trivial constant values
LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {} LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {}
| ^^^^^^ non-trivial anonymous constants must not depend on the parameter `T` | ^^^^^^ non-trivial anonymous constants must not depend on the parameter `T`
| |
= help: it is currently only allowed to use either `T` or `{ T }` as generic constants = note: type parameters are currently not permitted in anonymous constants
error[E0119]: conflicting implementations of trait `MyTrait`: error[E0119]: conflicting implementations of trait `MyTrait`:
--> $DIR/issue-64494.rs:19:1 --> $DIR/issue-64494.rs:19:1

View file

@ -4,7 +4,7 @@ error: generic parameters must not be used inside of non trivial constant values
LL | [0u8; mem::size_of::<Self::Associated>()]; LL | [0u8; mem::size_of::<Self::Associated>()];
| ^^^^^^^^^^^^^^^^ non-trivial anonymous constants must not depend on the parameter `Self` | ^^^^^^^^^^^^^^^^ non-trivial anonymous constants must not depend on the parameter `Self`
| |
= help: it is currently only allowed to use either `Self` or `{ Self }` as generic constants = note: type parameters are currently not permitted in anonymous constants
error: aborting due to previous error error: aborting due to previous error

View file

@ -0,0 +1,18 @@
error: constant expression depends on a generic parameter
--> $DIR/issue-76701-ty-param-in-const.rs:6:21
|
LL | fn ty_param<T>() -> [u8; std::mem::size_of::<T>()] {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this may fail depending on what value the parameter takes
error: constant expression depends on a generic parameter
--> $DIR/issue-76701-ty-param-in-const.rs:12:37
|
LL | fn const_param<const N: usize>() -> [u8; N + 1] {
| ^^^^^^^^^^^
|
= note: this may fail depending on what value the parameter takes
error: aborting due to 2 previous errors

View file

@ -0,0 +1,18 @@
error: generic parameters must not be used inside of non trivial constant values
--> $DIR/issue-76701-ty-param-in-const.rs:6:46
|
LL | fn ty_param<T>() -> [u8; std::mem::size_of::<T>()] {
| ^ non-trivial anonymous constants must not depend on the parameter `T`
|
= note: type parameters are currently not permitted in anonymous constants
error: generic parameters must not be used inside of non trivial constant values
--> $DIR/issue-76701-ty-param-in-const.rs:12:42
|
LL | fn const_param<const N: usize>() -> [u8; N + 1] {
| ^ non-trivial anonymous constants must not depend on the parameter `N`
|
= help: it is currently only allowed to use either `N` or `{ N }` as generic constants
error: aborting due to 2 previous errors

View file

@ -0,0 +1,18 @@
// revisions: full min
#![cfg_attr(full, feature(const_generics))]
#![cfg_attr(full, allow(incomplete_features))]
#![cfg_attr(min, feature(min_const_generics))]
fn ty_param<T>() -> [u8; std::mem::size_of::<T>()] {
//[full]~^ ERROR constant expression depends on a generic parameter
//[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
todo!()
}
fn const_param<const N: usize>() -> [u8; N + 1] {
//[full]~^ ERROR constant expression depends on a generic parameter
//[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
todo!()
}
fn main() {}

View file

@ -4,7 +4,7 @@ error: generic parameters must not be used inside of non trivial constant values
LL | fn t1() -> [u8; std::mem::size_of::<Self>()]; LL | fn t1() -> [u8; std::mem::size_of::<Self>()];
| ^^^^ non-trivial anonymous constants must not depend on the parameter `Self` | ^^^^ non-trivial anonymous constants must not depend on the parameter `Self`
| |
= help: it is currently only allowed to use either `Self` or `{ Self }` as generic constants = note: type parameters are currently not permitted in anonymous constants
error: generic `Self` types are currently not permitted in anonymous constants error: generic `Self` types are currently not permitted in anonymous constants
--> $DIR/self-ty-in-const-1.rs:14:41 --> $DIR/self-ty-in-const-1.rs:14:41

View file

@ -12,7 +12,7 @@ error: generic parameters must not be used inside of non trivial constant values
LL | struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U); LL | struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U);
| ^ non-trivial anonymous constants must not depend on the parameter `T` | ^ non-trivial anonymous constants must not depend on the parameter `T`
| |
= help: it is currently only allowed to use either `T` or `{ T }` as generic constants = note: type parameters are currently not permitted in anonymous constants
error: constant values inside of type parameter defaults must not depend on generic parameters error: constant values inside of type parameter defaults must not depend on generic parameters
--> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:12:21 --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:12:21

View file

@ -5,21 +5,21 @@
#![cfg_attr(min, feature(min_const_generics))] #![cfg_attr(min, feature(min_const_generics))]
trait SliceExt<T: Clone> { trait SliceExt<T: Clone> {
fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N>; fn array_windows_example<'a, const N: usize>(&'a self) -> ArrayWindowsExample<'a, T, N>;
} }
impl <T: Clone> SliceExt<T> for [T] { impl <T: Clone> SliceExt<T> for [T] {
fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N> { fn array_windows_example<'a, const N: usize>(&'a self) -> ArrayWindowsExample<'a, T, N> {
ArrayWindows{ idx: 0, slice: &self } ArrayWindowsExample{ idx: 0, slice: &self }
} }
} }
struct ArrayWindows<'a, T, const N: usize> { struct ArrayWindowsExample<'a, T, const N: usize> {
slice: &'a [T], slice: &'a [T],
idx: usize, idx: usize,
} }
impl <'a, T: Clone, const N: usize> Iterator for ArrayWindows<'a, T, N> { impl <'a, T: Clone, const N: usize> Iterator for ArrayWindowsExample<'a, T, N> {
type Item = [T; N]; type Item = [T; N];
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
// Note: this is unsound for some `T` and not meant as an example // Note: this is unsound for some `T` and not meant as an example
@ -45,7 +45,7 @@ const FOUR: usize = 4;
fn main() { fn main() {
let v: Vec<usize> = vec![0; 100]; let v: Vec<usize> = vec![0; 100];
for array in v.as_slice().array_windows::<FOUR>() { for array in v.as_slice().array_windows_example::<FOUR>() {
assert_eq!(array, [0, 0, 0, 0]) assert_eq!(array, [0, 0, 0, 0])
} }
} }