mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
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:
commit
285fc7d704
@ -591,14 +591,14 @@ pub trait GraphWalk<'a> {
|
||||
fn target(&'a self, edge: &Self::Edge) -> Self::Node;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub enum RenderOption {
|
||||
NoEdgeLabels,
|
||||
NoNodeLabels,
|
||||
NoEdgeStyles,
|
||||
NoNodeStyles,
|
||||
|
||||
Monospace,
|
||||
Fontname(String),
|
||||
DarkTheme,
|
||||
}
|
||||
|
||||
@ -633,11 +633,14 @@ where
|
||||
// Global graph properties
|
||||
let mut graph_attrs = Vec::new();
|
||||
let mut content_attrs = Vec::new();
|
||||
if options.contains(&RenderOption::Monospace) {
|
||||
let font = r#"fontname="Courier, monospace""#;
|
||||
graph_attrs.push(font);
|
||||
content_attrs.push(font);
|
||||
};
|
||||
let font;
|
||||
if let Some(fontname) = options.iter().find_map(|option| {
|
||||
if let RenderOption::Fontname(fontname) = option { Some(fontname) } else { None }
|
||||
}) {
|
||||
font = format!(r#"fontname="{}""#, fontname);
|
||||
graph_attrs.push(&font[..]);
|
||||
content_attrs.push(&font[..]);
|
||||
}
|
||||
if options.contains(&RenderOption::DarkTheme) {
|
||||
graph_attrs.push(r#"bgcolor="black""#);
|
||||
content_attrs.push(r#"color="white""#);
|
||||
|
@ -85,7 +85,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||
|
||||
debug!("try_report_named_anon_conflict: ret ty {:?}", ty);
|
||||
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
|
||||
// `impl` Trait that *isn't* caused by `async fn` desugaring, handle this case
|
||||
|
@ -961,7 +961,7 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: &
|
||||
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) {
|
||||
cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, |lint| {
|
||||
|
@ -170,7 +170,7 @@ impl Collector<'tcx> {
|
||||
feature_err(
|
||||
&self.tcx.sess.parse_sess,
|
||||
sym::static_nobundle,
|
||||
span.unwrap_or_else(|| rustc_span::DUMMY_SP),
|
||||
span.unwrap_or(rustc_span::DUMMY_SP),
|
||||
"kind=\"static-nobundle\" is unstable",
|
||||
)
|
||||
.emit();
|
||||
@ -179,7 +179,7 @@ impl Collector<'tcx> {
|
||||
feature_err(
|
||||
&self.tcx.sess.parse_sess,
|
||||
sym::raw_dylib,
|
||||
span.unwrap_or_else(|| rustc_span::DUMMY_SP),
|
||||
span.unwrap_or(rustc_span::DUMMY_SP),
|
||||
"kind=\"raw-dylib\" is unstable",
|
||||
)
|
||||
.emit();
|
||||
|
@ -273,10 +273,10 @@ pub trait PrettyPrinter<'tcx>:
|
||||
}
|
||||
|
||||
match self.tcx().trimmed_def_paths(LOCAL_CRATE).get(&def_id) {
|
||||
None => return Ok((self, false)),
|
||||
None => Ok((self, false)),
|
||||
Some(symbol) => {
|
||||
self.write_str(&symbol.as_str())?;
|
||||
return Ok((self, true));
|
||||
Ok((self, true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -387,7 +387,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
if let ReturnConstraint::ClosureUpvar(upvar) = kind {
|
||||
let def_id = match self.regioncx.universal_regions().defining_ty {
|
||||
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);
|
||||
|
@ -306,7 +306,8 @@ where
|
||||
let mut buf = Vec::new();
|
||||
|
||||
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 {
|
||||
render_opts.push(dot::RenderOption::DarkTheme);
|
||||
}
|
||||
|
@ -578,7 +578,7 @@ where
|
||||
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 });
|
||||
|
||||
|
@ -126,7 +126,7 @@ impl OptimizationFinder<'b, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
return None;
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,9 +55,9 @@ where
|
||||
writeln!(w, "{} {}Mir_{} {{", kind, cluster, def_name)?;
|
||||
|
||||
// Global graph properties
|
||||
let font = r#"fontname="Courier, monospace""#;
|
||||
let mut graph_attrs = vec![font];
|
||||
let mut content_attrs = vec![font];
|
||||
let font = format!(r#"fontname="{}""#, tcx.sess.opts.debugging_opts.graphviz_font);
|
||||
let mut graph_attrs = vec![&font[..]];
|
||||
let mut content_attrs = vec![&font[..]];
|
||||
|
||||
let dark_mode = tcx.sess.opts.debugging_opts.graphviz_dark_mode;
|
||||
if dark_mode {
|
||||
|
@ -466,7 +466,7 @@ impl<'a> Resolver<'a> {
|
||||
);
|
||||
err
|
||||
}
|
||||
ResolutionError::ParamInNonTrivialAnonConst(name) => {
|
||||
ResolutionError::ParamInNonTrivialAnonConst { name, is_type } => {
|
||||
let mut err = self.session.struct_span_err(
|
||||
span,
|
||||
"generic parameters must not be used inside of non trivial constant values",
|
||||
@ -478,9 +478,17 @@ impl<'a> Resolver<'a> {
|
||||
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
|
||||
}
|
||||
ResolutionError::SelfInTyParamDefault => {
|
||||
|
@ -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()) {
|
||||
([name], Some("&")) => {
|
||||
suggest_existing(err, &name.as_str()[..], &|name| format!("&{} ", name));
|
||||
|
@ -221,7 +221,7 @@ enum ResolutionError<'a> {
|
||||
/// generic parameters must not be used inside of non trivial constant values.
|
||||
///
|
||||
/// 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`
|
||||
SelfInTyParamDefault,
|
||||
/// Error E0767: use of unreachable label
|
||||
@ -2638,9 +2638,10 @@ impl<'a> Resolver<'a> {
|
||||
if record_used {
|
||||
self.report_error(
|
||||
span,
|
||||
ResolutionError::ParamInNonTrivialAnonConst(
|
||||
rib_ident.name,
|
||||
),
|
||||
ResolutionError::ParamInNonTrivialAnonConst {
|
||||
name: rib_ident.name,
|
||||
is_type: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
return Res::Err;
|
||||
@ -2718,7 +2719,10 @@ impl<'a> Resolver<'a> {
|
||||
if record_used {
|
||||
self.report_error(
|
||||
span,
|
||||
ResolutionError::ParamInNonTrivialAnonConst(rib_ident.name),
|
||||
ResolutionError::ParamInNonTrivialAnonConst {
|
||||
name: rib_ident.name,
|
||||
is_type: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
return Res::Err;
|
||||
|
@ -1762,6 +1762,10 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
||||
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 {
|
||||
match cg.lto {
|
||||
LtoCli::No | LtoCli::Unspecified => {}
|
||||
|
@ -911,6 +911,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
|
||||
"set the optimization fuel quota for a crate"),
|
||||
graphviz_dark_mode: bool = (false, parse_bool, [UNTRACKED],
|
||||
"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],
|
||||
"print some statistics about AST and HIR (default: no)"),
|
||||
human_readable_cgu_names: bool = (false, parse_bool, [TRACKED],
|
||||
|
@ -182,7 +182,7 @@ fn overlap_within_probe(
|
||||
}
|
||||
|
||||
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");
|
||||
return None;
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
// 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.
|
||||
if suggest_box { self.ret_type_span.clone() } else { None }
|
||||
if suggest_box { self.ret_type_span } else { None }
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
@ -1243,10 +1243,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
} else if check_completeness && !error_happened && !remaining_fields.is_empty() {
|
||||
let no_accessible_remaining_fields = remaining_fields
|
||||
.iter()
|
||||
.filter(|(_, (_, field))| {
|
||||
.find(|(_, (_, field))| {
|
||||
field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx)
|
||||
})
|
||||
.next()
|
||||
.is_none();
|
||||
|
||||
if no_accessible_remaining_fields {
|
||||
|
@ -1141,10 +1141,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
} else if !etc && !unmentioned_fields.is_empty() {
|
||||
let no_accessible_unmentioned_fields = unmentioned_fields
|
||||
.iter()
|
||||
.filter(|(field, _)| {
|
||||
.find(|(field, _)| {
|
||||
field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx)
|
||||
})
|
||||
.next()
|
||||
.is_none();
|
||||
|
||||
if no_accessible_unmentioned_fields {
|
||||
|
@ -76,6 +76,7 @@
|
||||
#![cfg_attr(test, feature(test))]
|
||||
#![feature(allocator_api)]
|
||||
#![feature(array_chunks)]
|
||||
#![feature(array_windows)]
|
||||
#![feature(allow_internal_unstable)]
|
||||
#![feature(arbitrary_self_types)]
|
||||
#![feature(box_patterns)]
|
||||
|
@ -97,6 +97,8 @@ pub use core::slice::check_range;
|
||||
pub use core::slice::ArrayChunks;
|
||||
#[unstable(feature = "array_chunks", issue = "74985")]
|
||||
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")]
|
||||
pub use core::slice::SliceIndex;
|
||||
#[stable(feature = "from_ref", since = "1.28.0")]
|
||||
|
@ -21,9 +21,9 @@ pub use self::future::Future;
|
||||
#[unstable(feature = "into_future", issue = "67644")]
|
||||
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};
|
||||
#[stable(feature = "future_readiness_fns", since = "1.47.0")]
|
||||
#[stable(feature = "future_readiness_fns", since = "1.48.0")]
|
||||
pub use ready::{ready, Ready};
|
||||
|
||||
#[unstable(feature = "future_poll_fn", issue = "72302")]
|
||||
|
@ -11,7 +11,7 @@ use crate::task::{Context, Poll};
|
||||
/// documentation for more.
|
||||
///
|
||||
/// [`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"]
|
||||
pub struct Pending<T> {
|
||||
_data: marker::PhantomData<T>,
|
||||
@ -31,12 +31,12 @@ pub struct Pending<T> {
|
||||
/// 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> {
|
||||
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> {
|
||||
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> {}
|
||||
|
||||
#[stable(feature = "future_readiness_fns", since = "1.47.0")]
|
||||
#[stable(feature = "future_readiness_fns", since = "1.48.0")]
|
||||
impl<T> Debug for Pending<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
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> {
|
||||
fn clone(&self) -> Self {
|
||||
pending()
|
||||
|
@ -8,15 +8,15 @@ use crate::task::{Context, Poll};
|
||||
/// documentation for more.
|
||||
///
|
||||
/// [`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)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
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> {}
|
||||
|
||||
#[stable(feature = "future_readiness_fns", since = "1.47.0")]
|
||||
#[stable(feature = "future_readiness_fns", since = "1.48.0")]
|
||||
impl<T> Future for Ready<T> {
|
||||
type Output = T;
|
||||
|
||||
@ -42,7 +42,7 @@ impl<T> Future for Ready<T> {
|
||||
/// 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> {
|
||||
Ready(Some(t))
|
||||
}
|
||||
|
@ -9,11 +9,8 @@ use crate::ops::Try;
|
||||
/// An iterator that yields `None` forever after the underlying iterator
|
||||
/// yields `None` once.
|
||||
///
|
||||
/// This `struct` is created by the [`fuse`] method on [`Iterator`]. See its
|
||||
/// documentation for more.
|
||||
///
|
||||
/// [`fuse`]: trait.Iterator.html#method.fuse
|
||||
/// [`Iterator`]: trait.Iterator.html
|
||||
/// This `struct` is created by [`Iterator::fuse`]. See its documentation
|
||||
/// for more.
|
||||
#[derive(Clone, Debug)]
|
||||
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -31,10 +31,10 @@ pub use crate::intrinsics::transmute;
|
||||
/// forever in an unreachable state. However, it does not guarantee that pointers
|
||||
/// to this memory will remain valid.
|
||||
///
|
||||
/// * If you want to leak memory, see [`Box::leak`][leak].
|
||||
/// * If you want to obtain a raw pointer to the memory, see [`Box::into_raw`][into_raw].
|
||||
/// * If you want to leak memory, see [`Box::leak`].
|
||||
/// * 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
|
||||
/// [`mem::drop`][drop].
|
||||
/// [`mem::drop`].
|
||||
///
|
||||
/// # 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
|
||||
/// running its destructor is entirely avoided.
|
||||
///
|
||||
/// [drop]: fn.drop.html
|
||||
/// [uninit]: fn.uninitialized.html
|
||||
/// [clone]: ../clone/trait.Clone.html
|
||||
/// [swap]: fn.swap.html
|
||||
/// [box]: ../../std/boxed/struct.Box.html
|
||||
/// [leak]: ../../std/boxed/struct.Box.html#method.leak
|
||||
/// [into_raw]: ../../std/boxed/struct.Box.html#method.into_raw
|
||||
/// [`Box`]: ../../std/boxed/struct.Box.html
|
||||
/// [`Box::leak`]: ../../std/boxed/struct.Box.html#method.leak
|
||||
/// [`Box::into_raw`]: ../../std/boxed/struct.Box.html#method.into_raw
|
||||
/// [`mem::drop`]: drop
|
||||
/// [ub]: ../../reference/behavior-considered-undefined.html
|
||||
/// [`ManuallyDrop`]: struct.ManuallyDrop.html
|
||||
#[inline]
|
||||
#[rustc_const_stable(feature = "const_forget", since = "1.46.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
|
||||
/// stabilized.
|
||||
///
|
||||
/// [`forget`]: fn.forget.html
|
||||
#[inline]
|
||||
#[unstable(feature = "forget_unsized", issue = "none")]
|
||||
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>());
|
||||
/// ```
|
||||
///
|
||||
/// [alignment]: ./fn.align_of.html
|
||||
/// [alignment]: align_of
|
||||
#[inline(always)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_promotable]
|
||||
@ -365,7 +359,6 @@ pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
|
||||
/// [slice]: ../../std/primitive.slice.html
|
||||
/// [trait object]: ../../book/ch17-02-trait-objects.html
|
||||
/// [extern type]: ../../unstable-book/language-features/extern-types.html
|
||||
/// [`size_of_val`]: ../../core/mem/fn.size_of_val.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -501,7 +494,6 @@ pub const fn align_of_val<T: ?Sized>(val: &T) -> usize {
|
||||
/// [slice]: ../../std/primitive.slice.html
|
||||
/// [trait object]: ../../book/ch17-02-trait-objects.html
|
||||
/// [extern type]: ../../unstable-book/language-features/extern-types.html
|
||||
/// [`align_of_val`]: ../../core/mem/fn.align_of_val.html
|
||||
///
|
||||
/// # 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
|
||||
/// 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
|
||||
///
|
||||
/// # Examples
|
||||
@ -595,9 +587,9 @@ pub const fn needs_drop<T>() -> bool {
|
||||
/// This has the same effect as [`MaybeUninit::zeroed().assume_init()`][zeroed].
|
||||
/// 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
|
||||
/// [inv]: union.MaybeUninit.html#initialization-invariant
|
||||
/// [inv]: MaybeUninit#initialization-invariant
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -650,10 +642,10 @@ pub unsafe fn zeroed<T>() -> T {
|
||||
/// (Notice that the rules around uninitialized integers are not finalized yet, but
|
||||
/// until they are, it is advisable to avoid them.)
|
||||
///
|
||||
/// [`MaybeUninit<T>`]: union.MaybeUninit.html
|
||||
/// [uninit]: union.MaybeUninit.html#method.uninit
|
||||
/// [assume_init]: union.MaybeUninit.html#method.assume_init
|
||||
/// [inv]: union.MaybeUninit.html#initialization-invariant
|
||||
/// [`MaybeUninit<T>`]: MaybeUninit
|
||||
/// [uninit]: MaybeUninit::uninit
|
||||
/// [assume_init]: MaybeUninit::assume_init
|
||||
/// [inv]: MaybeUninit#initialization-invariant
|
||||
#[inline(always)]
|
||||
#[rustc_deprecated(since = "1.39.0", reason = "use `mem::MaybeUninit` instead")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -686,9 +678,6 @@ pub unsafe fn uninitialized<T>() -> T {
|
||||
/// assert_eq!(42, x);
|
||||
/// assert_eq!(5, y);
|
||||
/// ```
|
||||
///
|
||||
/// [`replace`]: fn.replace.html
|
||||
/// [`take`]: fn.take.html
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
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.buf.len(), 0);
|
||||
/// ```
|
||||
///
|
||||
/// [`Clone`]: ../../std/clone/trait.Clone.html
|
||||
/// [`replace`]: fn.replace.html
|
||||
/// [`swap`]: fn.swap.html
|
||||
#[inline]
|
||||
#[stable(feature = "mem_take", since = "1.40.0")]
|
||||
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.buf[0], 2);
|
||||
/// ```
|
||||
///
|
||||
/// [`Clone`]: ../../std/clone/trait.Clone.html
|
||||
/// [`swap`]: fn.swap.html
|
||||
/// [`take`]: fn.take.html
|
||||
#[inline]
|
||||
#[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"]
|
||||
@ -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
|
||||
/// the function returns.
|
||||
///
|
||||
/// [drop]: ../ops/trait.Drop.html
|
||||
/// [drop]: Drop
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -894,8 +875,7 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
|
||||
/// println!("x: {}, y: {}", x, y.0); // still available
|
||||
/// ```
|
||||
///
|
||||
/// [`RefCell`]: ../../std/cell/struct.RefCell.html
|
||||
/// [`Copy`]: ../../std/marker/trait.Copy.html
|
||||
/// [`RefCell`]: crate::cell::RefCell
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn drop<T>(_x: T) {}
|
||||
@ -914,7 +894,6 @@ pub fn drop<T>(_x: T) {}
|
||||
/// `T`.
|
||||
///
|
||||
/// [ub]: ../../reference/behavior-considered-undefined.html
|
||||
/// [size_of]: fn.size_of.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -960,8 +939,6 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
|
||||
/// Opaque type representing the discriminant of an enum.
|
||||
///
|
||||
/// See the [`discriminant`] function in this module for more information.
|
||||
///
|
||||
/// [`discriminant`]: fn.discriminant.html
|
||||
#[stable(feature = "discriminant_value", since = "1.21.0")]
|
||||
pub struct Discriminant<T>(<T as DiscriminantKind>::Discriminant);
|
||||
|
||||
|
@ -166,6 +166,16 @@ from_str_float_impl!(f64);
|
||||
///
|
||||
/// This error is used as the error type for the [`FromStr`] implementation
|
||||
/// 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)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct ParseFloatError {
|
||||
|
@ -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
|
||||
/// [`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)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
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.
|
||||
///
|
||||
/// # 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(
|
||||
feature = "int_error_matching",
|
||||
reason = "it can be useful to match errors when making error messages \
|
||||
|
@ -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
|
||||
/// time), starting at the beginning of the slice.
|
||||
///
|
||||
|
@ -56,6 +56,9 @@ pub use iter::{RChunks, RChunksExact, RChunksExactMut, RChunksMut};
|
||||
#[unstable(feature = "array_chunks", issue = "74985")]
|
||||
pub use iter::{ArrayChunks, ArrayChunksMut};
|
||||
|
||||
#[unstable(feature = "array_windows", issue = "75027")]
|
||||
pub use iter::ArrayWindows;
|
||||
|
||||
#[unstable(feature = "split_inclusive", issue = "72360")]
|
||||
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
|
||||
/// of the slice.
|
||||
///
|
||||
|
@ -2,6 +2,7 @@
|
||||
#![feature(array_chunks)]
|
||||
#![feature(array_methods)]
|
||||
#![feature(array_map)]
|
||||
#![feature(array_windows)]
|
||||
#![feature(bool_to_option)]
|
||||
#![feature(bound_cloned)]
|
||||
#![feature(box_syntax)]
|
||||
|
@ -657,6 +657,55 @@ fn test_array_chunks_mut_zip() {
|
||||
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]
|
||||
fn test_rchunks_count() {
|
||||
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
|
||||
|
@ -9,7 +9,7 @@ pub use core::future::Future;
|
||||
pub use core::future::{from_generator, get_context, ResumeTy};
|
||||
|
||||
#[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};
|
||||
|
||||
#[doc(inline)]
|
||||
|
@ -118,7 +118,8 @@ impl Command {
|
||||
FDIO_SPAWN_CLONE_JOB
|
||||
| FDIO_SPAWN_CLONE_LDSVC
|
||||
| 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_argv().as_ptr(),
|
||||
envp,
|
||||
|
@ -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_STDIO: u32 = 0x0008;
|
||||
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;
|
||||
|
||||
// fdio_spawn_etc actions
|
||||
|
@ -1209,7 +1209,7 @@ impl<'a> Builder<'a> {
|
||||
cargo.env(format!("CC_{}", target.triple), &cc);
|
||||
|
||||
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) {
|
||||
let ranlib = format!("{} s", ar.display());
|
||||
@ -1394,7 +1394,7 @@ impl<'a> Builder<'a> {
|
||||
(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());
|
||||
}
|
||||
|
||||
|
@ -500,6 +500,7 @@ impl Config {
|
||||
|
||||
pub fn parse(args: &[String]) -> Config {
|
||||
let flags = Flags::parse(&args);
|
||||
|
||||
let mut config = Config::default_opts();
|
||||
config.exclude = flags.exclude;
|
||||
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();
|
||||
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
|
||||
} else if let Some(file_host) = build.host {
|
||||
file_host.iter().map(|h| TargetSelection::from_user(h)).collect()
|
||||
} else {
|
||||
vec![config.build]
|
||||
};
|
||||
config.targets = if let Some(arg_target) = flags.target.clone() {
|
||||
config.targets = if let Some(arg_target) = flags.target {
|
||||
arg_target
|
||||
} else if let Some(file_target) = build.target {
|
||||
file_target.iter().map(|h| TargetSelection::from_user(h)).collect()
|
||||
@ -628,14 +629,14 @@ impl Config {
|
||||
|
||||
config.verbose = cmp::max(config.verbose, flags.verbose);
|
||||
|
||||
if let Some(ref install) = toml.install {
|
||||
config.prefix = install.prefix.clone().map(PathBuf::from);
|
||||
config.sysconfdir = install.sysconfdir.clone().map(PathBuf::from);
|
||||
config.datadir = install.datadir.clone().map(PathBuf::from);
|
||||
config.docdir = install.docdir.clone().map(PathBuf::from);
|
||||
set(&mut config.bindir, install.bindir.clone().map(PathBuf::from));
|
||||
config.libdir = install.libdir.clone().map(PathBuf::from);
|
||||
config.mandir = install.mandir.clone().map(PathBuf::from);
|
||||
if let Some(install) = toml.install {
|
||||
config.prefix = install.prefix.map(PathBuf::from);
|
||||
config.sysconfdir = install.sysconfdir.map(PathBuf::from);
|
||||
config.datadir = install.datadir.map(PathBuf::from);
|
||||
config.docdir = install.docdir.map(PathBuf::from);
|
||||
set(&mut config.bindir, install.bindir.map(PathBuf::from));
|
||||
config.libdir = install.libdir.map(PathBuf::from);
|
||||
config.mandir = install.mandir.map(PathBuf::from);
|
||||
}
|
||||
|
||||
// We want the llvm-skip-rebuild flag to take precedence over the
|
||||
@ -658,7 +659,7 @@ impl Config {
|
||||
let mut optimize = None;
|
||||
let mut ignore_git = None;
|
||||
|
||||
if let Some(ref llvm) = toml.llvm {
|
||||
if let Some(llvm) = toml.llvm {
|
||||
match llvm.ccache {
|
||||
Some(StringOrBool::String(ref s)) => config.ccache = Some(s.to_string()),
|
||||
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_assertions = rust.debug_assertions;
|
||||
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.llvm_libunwind, rust.llvm_libunwind);
|
||||
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.verbose_tests, rust.verbose_tests);
|
||||
// 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.llvm_tools_enabled, rust.llvm_tools);
|
||||
config.rustc_parallel = rust.parallel_compiler.unwrap_or(false);
|
||||
config.rustc_default_linker = rust.default_linker.clone();
|
||||
config.musl_root = rust.musl_root.clone().map(PathBuf::from);
|
||||
config.save_toolstates = rust.save_toolstates.clone().map(PathBuf::from);
|
||||
config.rustc_default_linker = rust.default_linker;
|
||||
config.musl_root = rust.musl_root.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.backtrace_on_ice, rust.backtrace_on_ice);
|
||||
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);
|
||||
}
|
||||
|
||||
if let Some(ref t) = toml.target {
|
||||
if let Some(t) = toml.target {
|
||||
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 {
|
||||
target.llvm_config = Some(config.src.join(s));
|
||||
@ -792,18 +793,18 @@ impl Config {
|
||||
if let Some(s) = cfg.no_std {
|
||||
target.no_std = s;
|
||||
}
|
||||
target.cc = cfg.cc.clone().map(PathBuf::from);
|
||||
target.cxx = cfg.cxx.clone().map(PathBuf::from);
|
||||
target.ar = cfg.ar.clone().map(PathBuf::from);
|
||||
target.ranlib = cfg.ranlib.clone().map(PathBuf::from);
|
||||
target.linker = cfg.linker.clone().map(PathBuf::from);
|
||||
target.cc = cfg.cc.map(PathBuf::from);
|
||||
target.cxx = cfg.cxx.map(PathBuf::from);
|
||||
target.ar = cfg.ar.map(PathBuf::from);
|
||||
target.ranlib = cfg.ranlib.map(PathBuf::from);
|
||||
target.linker = cfg.linker.map(PathBuf::from);
|
||||
target.crt_static = cfg.crt_static;
|
||||
target.musl_root = cfg.musl_root.clone().map(PathBuf::from);
|
||||
target.musl_libdir = cfg.musl_libdir.clone().map(PathBuf::from);
|
||||
target.wasi_root = cfg.wasi_root.clone().map(PathBuf::from);
|
||||
target.qemu_rootfs = cfg.qemu_rootfs.clone().map(PathBuf::from);
|
||||
target.musl_root = cfg.musl_root.map(PathBuf::from);
|
||||
target.musl_libdir = cfg.musl_libdir.map(PathBuf::from);
|
||||
target.wasi_root = cfg.wasi_root.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)));
|
||||
}
|
||||
|
||||
if let Some(ref t) = toml.dist {
|
||||
config.dist_sign_folder = t.sign_folder.clone().map(PathBuf::from);
|
||||
config.dist_gpg_password_file = t.gpg_password_file.clone().map(PathBuf::from);
|
||||
config.dist_upload_addr = t.upload_addr.clone();
|
||||
if let Some(t) = toml.dist {
|
||||
config.dist_sign_folder = t.sign_folder.map(PathBuf::from);
|
||||
config.dist_gpg_password_file = t.gpg_password_file.map(PathBuf::from);
|
||||
config.dist_upload_addr = t.upload_addr;
|
||||
set(&mut config.rust_dist_src, t.src_tarball);
|
||||
set(&mut config.missing_tools, t.missing_tools);
|
||||
}
|
||||
|
@ -105,15 +105,13 @@ pub fn format(build: &Build, check: bool) {
|
||||
eprintln!("./x.py fmt is not supported on this channel");
|
||||
std::process::exit(1);
|
||||
});
|
||||
let src = build.src.clone();
|
||||
let walker = WalkBuilder::new(&build.src).types(matcher).overrides(ignore_fmt).build_parallel();
|
||||
let src = &build.src;
|
||||
let walker = WalkBuilder::new(src).types(matcher).overrides(ignore_fmt).build_parallel();
|
||||
walker.run(|| {
|
||||
let src = src.clone();
|
||||
let rustfmt_path = rustfmt_path.clone();
|
||||
Box::new(move |entry| {
|
||||
let entry = t!(entry);
|
||||
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
|
||||
})
|
||||
|
@ -30,8 +30,8 @@ impl Finder {
|
||||
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> {
|
||||
let cmd: OsString = cmd.as_ref().into();
|
||||
pub fn maybe_have<S: Into<OsString>>(&mut self, cmd: S) -> Option<PathBuf> {
|
||||
let cmd: OsString = cmd.into();
|
||||
let path = &self.path;
|
||||
self.cache
|
||||
.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
|
@ -16,6 +16,16 @@
|
||||
|
||||
#[macro_use]
|
||||
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_pretty;
|
||||
extern crate rustc_attr;
|
||||
@ -42,8 +52,6 @@ extern crate rustc_target;
|
||||
extern crate rustc_trait_selection;
|
||||
extern crate rustc_typeck;
|
||||
extern crate test as testing;
|
||||
#[macro_use]
|
||||
extern crate tracing;
|
||||
|
||||
use std::default::Default;
|
||||
use std::env;
|
||||
|
@ -8,7 +8,7 @@ use crate::clean;
|
||||
use crate::clean::*;
|
||||
use crate::core::DocContext;
|
||||
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;
|
||||
|
||||
pub const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = Pass {
|
||||
@ -48,15 +48,11 @@ pub(crate) struct Tests {
|
||||
pub(crate) found_tests: usize,
|
||||
}
|
||||
|
||||
impl Tests {
|
||||
pub(crate) fn new() -> Tests {
|
||||
Tests { found_tests: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::doctest::Tester for Tests {
|
||||
fn add_test(&mut self, _: String, _: LangString, _: usize) {
|
||||
self.found_tests += 1;
|
||||
fn add_test(&mut self, _: String, config: LangString, _: usize) {
|
||||
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);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
+-------------------------------------+------------+------------+------------+------------+
|
||||
| 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% |
|
||||
+-------------------------------------+------------+------------+------------+------------+
|
||||
|
12
src/test/rustdoc-ui/private-doc-test.rs
Normal file
12
src/test/rustdoc-ui/private-doc-test.rs
Normal 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() {}
|
||||
}
|
@ -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 {}
|
||||
| ^^^^^^ 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
|
||||
--> $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 {}
|
||||
| ^^^^^^ 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`:
|
||||
--> $DIR/issue-64494.rs:19:1
|
||||
|
@ -4,7 +4,7 @@ error: generic parameters must not be used inside of non trivial constant values
|
||||
LL | [0u8; mem::size_of::<Self::Associated>()];
|
||||
| ^^^^^^^^^^^^^^^^ 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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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() {}
|
@ -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>()];
|
||||
| ^^^^ 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
|
||||
--> $DIR/self-ty-in-const-1.rs:14:41
|
||||
|
@ -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);
|
||||
| ^ 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
|
||||
--> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:12:21
|
||||
|
@ -5,21 +5,21 @@
|
||||
#![cfg_attr(min, feature(min_const_generics))]
|
||||
|
||||
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] {
|
||||
fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N> {
|
||||
ArrayWindows{ idx: 0, slice: &self }
|
||||
fn array_windows_example<'a, const N: usize>(&'a self) -> ArrayWindowsExample<'a, T, N> {
|
||||
ArrayWindowsExample{ idx: 0, slice: &self }
|
||||
}
|
||||
}
|
||||
|
||||
struct ArrayWindows<'a, T, const N: usize> {
|
||||
struct ArrayWindowsExample<'a, T, const N: usize> {
|
||||
slice: &'a [T],
|
||||
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];
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
// Note: this is unsound for some `T` and not meant as an example
|
||||
@ -45,7 +45,7 @@ const FOUR: usize = 4;
|
||||
fn main() {
|
||||
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])
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user