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
54 changed files with 450 additions and 164 deletions
|
@ -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""#);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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| {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 });
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ impl OptimizationFinder<'b, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return None;
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 => {}
|
||||||
|
|
|
@ -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],
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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")]
|
||||||
|
|
|
@ -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")]
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")]
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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.
|
||||||
///
|
///
|
||||||
|
|
|
@ -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.
|
||||||
///
|
///
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
})
|
})
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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% |
|
||||||
+-------------------------------------+------------+------------+------------+------------+
|
+-------------------------------------+------------+------------+------------+------------+
|
||||||
|
|
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 {}
|
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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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>()];
|
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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue