diff --git a/.editorconfig b/.editorconfig index 6c8560aa1f543..d2d788d2172f7 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,6 +12,9 @@ trim_trailing_whitespace = true indent_style = space indent_size = 4 +[*.css] +indent_style = tab + # some tests need trailing whitespace in output snapshots [tests/**] trim_trailing_whitespace = false diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index fbb582fe86018..85b515f2ef9cb 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -702,7 +702,9 @@ pub(crate) fn global_llvm_features(sess: &Session, only_base_features: bool) -> features_string }; - features.extend(features_string.split(',').map(String::from)); + if !features_string.is_empty() { + features.extend(features_string.split(',').map(String::from)); + } } Some(_) | None => {} }; diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 39e886227d946..ebb912ed90d0b 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -257,6 +257,8 @@ declare_features! ( (internal, rustc_attrs, "1.0.0", None), /// Allows using the `#[stable]` and `#[unstable]` attributes. (internal, staged_api, "1.0.0", None), + /// Perma-unstable, only used to test the `incomplete_features` lint. + (incomplete, test_incomplete_feature, "CURRENT_RUSTC_VERSION", None), /// Added for testing unstable lints; perma-unstable. (internal, test_unstable_lint, "1.60.0", None), /// Use for stable + negative coherence and strict coherence depending on trait's diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index cdd8f3f42c3f2..fc8455dff9258 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1033,8 +1033,8 @@ declare_lint! { /// ```rust /// #[warn(unused_macro_rules)] /// macro_rules! unused_empty { - /// (hello) => { println!("Hello, world!") }; // This rule is unused - /// () => { println!("empty") }; // This rule is used + /// (hello) => { println!("Hello, world!") }; // This rule is used + /// () => { println!("empty") }; // This rule is unused /// } /// /// fn main() { diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index aae815c0be046..bd8c022ef42a6 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -65,7 +65,7 @@ impl<'tcx> BasicBlocks<'tcx> { /// Returns basic blocks in a reverse postorder. /// - /// See [`traversal::reverse_postorder`]'s docs to learn what is preorder traversal. + /// See [`traversal::reverse_postorder`]'s docs to learn what is postorder traversal. /// /// [`traversal::reverse_postorder`]: crate::mir::traversal::reverse_postorder #[inline] diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 72330eab30d58..33c38adcef058 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -136,8 +136,12 @@ pub struct QueryVTable<'tcx, C: QueryCache> { /// For `no_hash` queries, this function pointer is None. pub hash_value_fn: Option, &C::Value) -> Fingerprint>, - pub value_from_cycle_error: - fn(tcx: TyCtxt<'tcx>, cycle_error: CycleError, guar: ErrorGuaranteed) -> C::Value, + pub value_from_cycle_error: fn( + tcx: TyCtxt<'tcx>, + key: C::Key, + cycle_error: CycleError, + guar: ErrorGuaranteed, + ) -> C::Value, pub format_value: fn(&C::Value) -> String, /// Formats a human-readable description of this query and its key, as diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index dee08d34427fe..a59798dafbda9 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -109,21 +109,21 @@ impl<'tcx> MaybePlacesSwitchIntData<'tcx> { /// ```rust /// struct S; /// #[rustfmt::skip] -/// fn foo(pred: bool) { // maybe-init: -/// // {} -/// let a = S; let mut b = S; let c; let d; // {a, b} +/// fn foo(p: bool) { // maybe-init: +/// // {p} +/// let a = S; let mut b = S; let c; let d; // {p, a, b} /// -/// if pred { -/// drop(a); // { b} -/// b = S; // { b} +/// if p { +/// drop(a); // {p, b} +/// b = S; // {p, b} /// /// } else { -/// drop(b); // {a} -/// d = S; // {a, d} +/// drop(b); // {p, a} +/// d = S; // {p, a, d} /// -/// } // {a, b, d} +/// } // {p, a, b, d} /// -/// c = S; // {a, b, c, d} +/// c = S; // {p, a, b, c, d} /// } /// ``` /// @@ -199,11 +199,11 @@ impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> { /// ```rust /// struct S; /// #[rustfmt::skip] -/// fn foo(pred: bool) { // maybe-uninit: +/// fn foo(p: bool) { // maybe-uninit: /// // {a, b, c, d} /// let a = S; let mut b = S; let c; let d; // { c, d} /// -/// if pred { +/// if p { /// drop(a); // {a, c, d} /// b = S; // {a, c, d} /// @@ -279,34 +279,36 @@ impl<'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { } } -/// `EverInitializedPlaces` tracks all places that might have ever been -/// initialized upon reaching a particular point in the control flow -/// for a function, without an intervening `StorageDead`. +/// `EverInitializedPlaces` tracks all initializations that may have occurred +/// upon reaching a particular point in the control flow for a function, +/// without an intervening `StorageDead`. /// /// This dataflow is used to determine if an immutable local variable may /// be assigned to. /// /// For example, in code like the following, we have corresponding -/// dataflow information shown in the right-hand comments. +/// dataflow information shown in the right-hand comments. Underscored indices +/// are used to distinguish between multiple initializations of the same local +/// variable, e.g. `b_0` and `b_1`. /// /// ```rust /// struct S; /// #[rustfmt::skip] -/// fn foo(pred: bool) { // ever-init: -/// // { } -/// let a = S; let mut b = S; let c; let d; // {a, b } +/// fn foo(p: bool) { // ever-init: +/// // {p, } +/// let a = S; let mut b = S; let c; let d; // {p, a, b_0, } /// -/// if pred { -/// drop(a); // {a, b, } -/// b = S; // {a, b, } +/// if p { +/// drop(a); // {p, a, b_0, } +/// b = S; // {p, a, b_0, b_1, } /// /// } else { -/// drop(b); // {a, b, } -/// d = S; // {a, b, d } +/// drop(b); // {p, a, b_0, b_1, } +/// d = S; // {p, a, b_0, b_1, d} /// -/// } // {a, b, d } +/// } // {p, a, b_0, b_1, d} /// -/// c = S; // {a, b, c, d } +/// c = S; // {p, a, b_0, b_1, c, d} /// } /// ``` pub struct EverInitializedPlaces<'a, 'tcx> { diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index a892958d6a810..d8dc004f1cf7a 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -125,17 +125,18 @@ where fn mk_cycle<'tcx, C: QueryCache>( query: &'tcx QueryVTable<'tcx, C>, tcx: TyCtxt<'tcx>, + key: C::Key, cycle_error: CycleError, ) -> C::Value { let error = report_cycle(tcx.sess, &cycle_error); match query.cycle_error_handling { CycleErrorHandling::Error => { let guar = error.emit(); - (query.value_from_cycle_error)(tcx, cycle_error, guar) + (query.value_from_cycle_error)(tcx, key, cycle_error, guar) } CycleErrorHandling::DelayBug => { let guar = error.delay_as_bug(); - (query.value_from_cycle_error)(tcx, cycle_error, guar) + (query.value_from_cycle_error)(tcx, key, cycle_error, guar) } } } @@ -219,6 +220,7 @@ where fn cycle_error<'tcx, C: QueryCache>( query: &'tcx QueryVTable<'tcx, C>, tcx: TyCtxt<'tcx>, + key: C::Key, try_execute: QueryJobId, span: Span, ) -> (C::Value, Option) { @@ -229,7 +231,7 @@ fn cycle_error<'tcx, C: QueryCache>( .expect("failed to collect active queries"); let error = find_cycle_in_stack(try_execute, job_map, ¤t_query_job(), span); - (mk_cycle(query, tcx, error.lift()), None) + (mk_cycle(query, tcx, key, error.lift()), None) } #[inline(always)] @@ -274,7 +276,7 @@ fn wait_for_query<'tcx, C: QueryCache>( (v, Some(index)) } - Err(cycle) => (mk_cycle(query, tcx, cycle.lift()), None), + Err(cycle) => (mk_cycle(query, tcx, key, cycle.lift()), None), } } @@ -337,7 +339,7 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>( // If we are single-threaded we know that we have cycle error, // so we just return the error. - cycle_error(query, tcx, id, span) + cycle_error(query, tcx, key, id, span) } } ActiveKeyStatus::Poisoned => FatalError.raise(), diff --git a/compiler/rustc_query_impl/src/from_cycle_error.rs b/compiler/rustc_query_impl/src/from_cycle_error.rs index 0b7f69765823f..c69d3eb9a0f05 100644 --- a/compiler/rustc_query_impl/src/from_cycle_error.rs +++ b/compiler/rustc_query_impl/src/from_cycle_error.rs @@ -15,34 +15,34 @@ use rustc_middle::query::erase::erase_val; use rustc_middle::ty::layout::{LayoutError, TyAndLayout}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; -use rustc_span::def_id::LocalDefId; +use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::{ErrorGuaranteed, Span}; use crate::job::report_cycle; pub(crate) fn specialize_query_vtables<'tcx>(vtables: &mut QueryVTables<'tcx>) { vtables.type_of.value_from_cycle_error = - |tcx, _, guar| erase_val(ty::EarlyBinder::bind(Ty::new_error(tcx, guar))); + |tcx, _, _, guar| erase_val(ty::EarlyBinder::bind(Ty::new_error(tcx, guar))); vtables.type_of_opaque_hir_typeck.value_from_cycle_error = - |tcx, _, guar| erase_val(ty::EarlyBinder::bind(Ty::new_error(tcx, guar))); + |tcx, _, _, guar| erase_val(ty::EarlyBinder::bind(Ty::new_error(tcx, guar))); vtables.erase_and_anonymize_regions_ty.value_from_cycle_error = - |tcx, _, guar| erase_val(Ty::new_error(tcx, guar)); + |tcx, _, _, guar| erase_val(Ty::new_error(tcx, guar)); - vtables.fn_sig.value_from_cycle_error = |tcx, cycle, guar| erase_val(fn_sig(tcx, cycle, guar)); + vtables.fn_sig.value_from_cycle_error = |tcx, key, _, guar| erase_val(fn_sig(tcx, key, guar)); vtables.check_representability.value_from_cycle_error = - |tcx, cycle, guar| check_representability(tcx, cycle, guar); + |tcx, _, cycle, guar| check_representability(tcx, cycle, guar); vtables.check_representability_adt_ty.value_from_cycle_error = - |tcx, cycle, guar| check_representability(tcx, cycle, guar); + |tcx, _, cycle, guar| check_representability(tcx, cycle, guar); vtables.variances_of.value_from_cycle_error = - |tcx, cycle, guar| erase_val(variances_of(tcx, cycle, guar)); + |tcx, _, cycle, guar| erase_val(variances_of(tcx, cycle, guar)); vtables.layout_of.value_from_cycle_error = - |tcx, cycle, guar| erase_val(layout_of(tcx, cycle, guar)); + |tcx, _, cycle, guar| erase_val(layout_of(tcx, cycle, guar)); } pub(crate) fn default<'tcx>(tcx: TyCtxt<'tcx>, cycle_error: CycleError, query_name: &str) -> ! { @@ -57,15 +57,12 @@ pub(crate) fn default<'tcx>(tcx: TyCtxt<'tcx>, cycle_error: CycleError, query_na fn fn_sig<'tcx>( tcx: TyCtxt<'tcx>, - cycle_error: CycleError, + def_id: DefId, guar: ErrorGuaranteed, ) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> { let err = Ty::new_error(tcx, guar); - let arity = if let Some(info) = cycle_error.cycle.get(0) - && info.frame.dep_kind == DepKind::fn_sig - && let Some(def_id) = info.frame.def_id - && let Some(node) = tcx.hir_get_if_local(def_id) + let arity = if let Some(node) = tcx.hir_get_if_local(def_id) && let Some(sig) = node.fn_sig() { sig.decl.inputs.len() diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index ddce892345907..78d5fd3de1f00 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -487,7 +487,7 @@ macro_rules! define_queries { #[cfg(not($cache_on_disk))] is_loadable_from_disk_fn: |_tcx, _key, _index| false, - value_from_cycle_error: |tcx, cycle, _| { + value_from_cycle_error: |tcx, _, cycle, _| { $crate::from_cycle_error::default(tcx, cycle, stringify!($name)) }, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 48cdf46b821f9..cd437357456e1 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2006,6 +2006,7 @@ symbols! { test_2018_feature, test_accepted_feature, test_case, + test_incomplete_feature, test_removed_feature, test_runner, test_unstable_lint, diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 4a2cf15277441..e78a442e97600 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -1003,9 +1003,10 @@ impl const Drop for Guard<'_, T> { /// dropped. /// /// Used for [`Iterator::next_chunk`]. +#[rustc_const_unstable(feature = "const_iter", issue = "92476")] #[inline] -pub(crate) fn iter_next_chunk( - iter: &mut impl Iterator, +pub(crate) const fn iter_next_chunk( + iter: &mut impl [const] Iterator, ) -> Result<[T; N], IntoIter> { let mut array = [const { MaybeUninit::uninit() }; N]; let r = iter_next_chunk_erased(&mut array, iter); @@ -1026,10 +1027,11 @@ pub(crate) fn iter_next_chunk( /// /// Unfortunately this loop has two exit conditions, the buffer filling up /// or the iterator running out of items, making it tend to optimize poorly. +#[rustc_const_unstable(feature = "const_iter", issue = "92476")] #[inline] -fn iter_next_chunk_erased( +const fn iter_next_chunk_erased( buffer: &mut [MaybeUninit], - iter: &mut impl Iterator, + iter: &mut impl [const] Iterator, ) -> Result<(), usize> { // if `Iterator::next` panics, this guard will drop already initialized items let mut guard = Guard { array_mut: buffer, initialized: 0 }; diff --git a/library/core/src/iter/adapters/array_chunks.rs b/library/core/src/iter/adapters/array_chunks.rs index 7c003cff10c7b..a3e5ae5e7698b 100644 --- a/library/core/src/iter/adapters/array_chunks.rs +++ b/library/core/src/iter/adapters/array_chunks.rs @@ -26,7 +26,7 @@ where I: Iterator, { #[track_caller] - pub(in crate::iter) fn new(iter: I) -> Self { + pub(in crate::iter) const fn new(iter: I) -> Self { assert!(N != 0, "chunk size must be non-zero"); Self { iter, remainder: None } } diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs index 0ece54554d464..d143b67fd4353 100644 --- a/library/core/src/iter/adapters/chain.rs +++ b/library/core/src/iter/adapters/chain.rs @@ -33,7 +33,7 @@ pub struct Chain { b: Option, } impl Chain { - pub(in super::super) fn new(a: A, b: B) -> Chain { + pub(in super::super) const fn new(a: A, b: B) -> Chain { Chain { a: Some(a), b: Some(b) } } } diff --git a/library/core/src/iter/adapters/cloned.rs b/library/core/src/iter/adapters/cloned.rs index aea6d64281aec..54d132813e4db 100644 --- a/library/core/src/iter/adapters/cloned.rs +++ b/library/core/src/iter/adapters/cloned.rs @@ -20,7 +20,7 @@ pub struct Cloned { } impl Cloned { - pub(in crate::iter) fn new(it: I) -> Cloned { + pub(in crate::iter) const fn new(it: I) -> Cloned { Cloned { it } } } diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index 9627ace29795c..ba87fb7216059 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -21,7 +21,7 @@ pub struct Copied { } impl Copied { - pub(in crate::iter) fn new(it: I) -> Copied { + pub(in crate::iter) const fn new(it: I) -> Copied { Copied { it } } diff --git a/library/core/src/iter/adapters/cycle.rs b/library/core/src/iter/adapters/cycle.rs index 6cb1a3a46763e..8fb54efbd3209 100644 --- a/library/core/src/iter/adapters/cycle.rs +++ b/library/core/src/iter/adapters/cycle.rs @@ -18,7 +18,11 @@ pub struct Cycle { } impl Cycle { - pub(in crate::iter) fn new(iter: I) -> Cycle { + #[rustc_const_unstable(feature = "const_iter", issue = "92476")] + pub(in crate::iter) const fn new(iter: I) -> Cycle + where + I: [const] Clone, + { Cycle { orig: iter.clone(), iter } } } diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index f7b9f0b7a5e9d..916ba88e6160a 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -20,7 +20,7 @@ pub struct Enumerate { count: usize, } impl Enumerate { - pub(in crate::iter) fn new(iter: I) -> Enumerate { + pub(in crate::iter) const fn new(iter: I) -> Enumerate { Enumerate { iter, count: 0 } } diff --git a/library/core/src/iter/adapters/filter.rs b/library/core/src/iter/adapters/filter.rs index b22419ccf080a..cf21536784a28 100644 --- a/library/core/src/iter/adapters/filter.rs +++ b/library/core/src/iter/adapters/filter.rs @@ -24,7 +24,7 @@ pub struct Filter { predicate: P, } impl Filter { - pub(in crate::iter) fn new(iter: I, predicate: P) -> Filter { + pub(in crate::iter) const fn new(iter: I, predicate: P) -> Filter { Filter { iter, predicate } } } diff --git a/library/core/src/iter/adapters/filter_map.rs b/library/core/src/iter/adapters/filter_map.rs index 24ec6b1741ce1..3fd7e16d1c148 100644 --- a/library/core/src/iter/adapters/filter_map.rs +++ b/library/core/src/iter/adapters/filter_map.rs @@ -20,7 +20,7 @@ pub struct FilterMap { f: F, } impl FilterMap { - pub(in crate::iter) fn new(iter: I, f: F) -> FilterMap { + pub(in crate::iter) const fn new(iter: I, f: F) -> FilterMap { FilterMap { iter, f } } } diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index c50f07ff6bb66..02a416e6cc869 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -186,7 +186,11 @@ pub struct Flatten> { } impl> Flatten { - pub(in super::super) fn new(iter: I) -> Flatten { + #[rustc_const_unstable(feature = "const_iter", issue = "92476")] + pub(in super::super) const fn new(iter: I) -> Flatten + where + I: [const] Iterator, + { Flatten { inner: FlattenCompat::new(iter) } } } @@ -363,7 +367,11 @@ where I: Iterator, { /// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`. - fn new(iter: I) -> FlattenCompat { + #[rustc_const_unstable(feature = "const_iter", issue = "92476")] + const fn new(iter: I) -> FlattenCompat + where + I: [const] Iterator, + { FlattenCompat { iter: iter.fuse(), frontiter: None, backiter: None } } } diff --git a/library/core/src/iter/adapters/fuse.rs b/library/core/src/iter/adapters/fuse.rs index 0072a95e8dfe0..ef956e8bdef5d 100644 --- a/library/core/src/iter/adapters/fuse.rs +++ b/library/core/src/iter/adapters/fuse.rs @@ -21,7 +21,7 @@ pub struct Fuse { iter: Option, } impl Fuse { - pub(in crate::iter) fn new(iter: I) -> Fuse { + pub(in crate::iter) const fn new(iter: I) -> Fuse { Fuse { iter: Some(iter) } } diff --git a/library/core/src/iter/adapters/inspect.rs b/library/core/src/iter/adapters/inspect.rs index 0e2a68a503e44..de94951bc80ff 100644 --- a/library/core/src/iter/adapters/inspect.rs +++ b/library/core/src/iter/adapters/inspect.rs @@ -20,7 +20,7 @@ pub struct Inspect { f: F, } impl Inspect { - pub(in crate::iter) fn new(iter: I, f: F) -> Inspect { + pub(in crate::iter) const fn new(iter: I, f: F) -> Inspect { Inspect { iter, f } } } diff --git a/library/core/src/iter/adapters/map_while.rs b/library/core/src/iter/adapters/map_while.rs index c047c40de050e..3e34427da6142 100644 --- a/library/core/src/iter/adapters/map_while.rs +++ b/library/core/src/iter/adapters/map_while.rs @@ -20,7 +20,7 @@ pub struct MapWhile { } impl MapWhile { - pub(in crate::iter) fn new(iter: I, predicate: P) -> MapWhile { + pub(in crate::iter) const fn new(iter: I, predicate: P) -> MapWhile { MapWhile { iter, predicate } } } diff --git a/library/core/src/iter/adapters/map_windows.rs b/library/core/src/iter/adapters/map_windows.rs index cef556319143e..a976e5e7bce49 100644 --- a/library/core/src/iter/adapters/map_windows.rs +++ b/library/core/src/iter/adapters/map_windows.rs @@ -46,7 +46,7 @@ struct Buffer { } impl MapWindows { - pub(in crate::iter) fn new(iter: I, f: F) -> Self { + pub(in crate::iter) const fn new(iter: I, f: F) -> Self { assert!(N != 0, "array in `Iterator::map_windows` must contain more than 0 elements"); // Only ZST arrays' length can be so large. @@ -63,7 +63,7 @@ impl MapWindows { impl MapWindowsInner { #[inline] - fn new(iter: I) -> Self { + const fn new(iter: I) -> Self { Self { iter: Some(iter), buffer: None } } diff --git a/library/core/src/iter/adapters/peekable.rs b/library/core/src/iter/adapters/peekable.rs index 9f6d1df57dbe8..4bddc2025c26e 100644 --- a/library/core/src/iter/adapters/peekable.rs +++ b/library/core/src/iter/adapters/peekable.rs @@ -21,7 +21,7 @@ pub struct Peekable { } impl Peekable { - pub(in crate::iter) fn new(iter: I) -> Peekable { + pub(in crate::iter) const fn new(iter: I) -> Peekable { Peekable { iter, peeked: None } } } diff --git a/library/core/src/iter/adapters/rev.rs b/library/core/src/iter/adapters/rev.rs index 17d3eef597dcb..b9ada504525f9 100644 --- a/library/core/src/iter/adapters/rev.rs +++ b/library/core/src/iter/adapters/rev.rs @@ -17,7 +17,7 @@ pub struct Rev { } impl Rev { - pub(in crate::iter) fn new(iter: T) -> Rev { + pub(in crate::iter) const fn new(iter: T) -> Rev { Rev { iter } } diff --git a/library/core/src/iter/adapters/scan.rs b/library/core/src/iter/adapters/scan.rs index e12375c94e067..7d084a89bd940 100644 --- a/library/core/src/iter/adapters/scan.rs +++ b/library/core/src/iter/adapters/scan.rs @@ -21,7 +21,7 @@ pub struct Scan { } impl Scan { - pub(in crate::iter) fn new(iter: I, state: St, f: F) -> Scan { + pub(in crate::iter) const fn new(iter: I, state: St, f: F) -> Scan { Scan { iter, state, f } } } diff --git a/library/core/src/iter/adapters/skip.rs b/library/core/src/iter/adapters/skip.rs index 55c4a7f14fbd6..f7a6beb2b8c63 100644 --- a/library/core/src/iter/adapters/skip.rs +++ b/library/core/src/iter/adapters/skip.rs @@ -24,7 +24,7 @@ pub struct Skip { } impl Skip { - pub(in crate::iter) fn new(iter: I, n: usize) -> Skip { + pub(in crate::iter) const fn new(iter: I, n: usize) -> Skip { Skip { iter, n } } } diff --git a/library/core/src/iter/adapters/skip_while.rs b/library/core/src/iter/adapters/skip_while.rs index 8ae453e76fa0d..ced4fd8f2abc4 100644 --- a/library/core/src/iter/adapters/skip_while.rs +++ b/library/core/src/iter/adapters/skip_while.rs @@ -21,7 +21,7 @@ pub struct SkipWhile { } impl SkipWhile { - pub(in crate::iter) fn new(iter: I, predicate: P) -> SkipWhile { + pub(in crate::iter) const fn new(iter: I, predicate: P) -> SkipWhile { SkipWhile { iter, flag: false, predicate } } } diff --git a/library/core/src/iter/adapters/take.rs b/library/core/src/iter/adapters/take.rs index b96335f415257..ecd462c60eda3 100644 --- a/library/core/src/iter/adapters/take.rs +++ b/library/core/src/iter/adapters/take.rs @@ -20,7 +20,7 @@ pub struct Take { } impl Take { - pub(in crate::iter) fn new(iter: I, n: usize) -> Take { + pub(in crate::iter) const fn new(iter: I, n: usize) -> Take { Take { iter, n } } } diff --git a/library/core/src/iter/adapters/take_while.rs b/library/core/src/iter/adapters/take_while.rs index 06028ea98e7fd..6e40629567a83 100644 --- a/library/core/src/iter/adapters/take_while.rs +++ b/library/core/src/iter/adapters/take_while.rs @@ -21,7 +21,7 @@ pub struct TakeWhile { } impl TakeWhile { - pub(in crate::iter) fn new(iter: I, predicate: P) -> TakeWhile { + pub(in crate::iter) const fn new(iter: I, predicate: P) -> TakeWhile { TakeWhile { iter, flag: false, predicate } } } diff --git a/library/core/src/iter/traits/accum.rs b/library/core/src/iter/traits/accum.rs index 375b5ef52859f..3787e41f0a0b1 100644 --- a/library/core/src/iter/traits/accum.rs +++ b/library/core/src/iter/traits/accum.rs @@ -10,11 +10,12 @@ use crate::num::{Saturating, Wrapping}; /// [`sum()`]: Iterator::sum /// [`FromIterator`]: iter::FromIterator #[stable(feature = "iter_arith_traits", since = "1.12.0")] +#[rustc_const_unstable(feature = "const_iter", issue = "92476")] #[diagnostic::on_unimplemented( message = "a value of type `{Self}` cannot be made by summing an iterator over elements of type `{A}`", label = "value of type `{Self}` cannot be made by summing a `std::iter::Iterator`" )] -pub trait Sum: Sized { +pub const trait Sum: Sized { /// Takes an iterator and generates `Self` from the elements by "summing up" /// the items. #[stable(feature = "iter_arith_traits", since = "1.12.0")] @@ -31,11 +32,12 @@ pub trait Sum: Sized { /// [`product()`]: Iterator::product /// [`FromIterator`]: iter::FromIterator #[stable(feature = "iter_arith_traits", since = "1.12.0")] +#[rustc_const_unstable(feature = "const_iter", issue = "92476")] #[diagnostic::on_unimplemented( message = "a value of type `{Self}` cannot be made by multiplying all elements of type `{A}` from an iterator", label = "value of type `{Self}` cannot be made by multiplying all elements from a `std::iter::Iterator`" )] -pub trait Product: Sized { +pub const trait Product: Sized { /// Takes an iterator and generates `Self` from the elements by multiplying /// the items. #[stable(feature = "iter_arith_traits", since = "1.12.0")] diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 2e82f45771823..dc2dd1d35bea0 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -7,6 +7,7 @@ use super::super::{ use super::TrustedLen; use crate::array; use crate::cmp::{self, Ordering}; +use crate::marker::Destruct; use crate::num::NonZero; use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, Residual, Try}; @@ -108,7 +109,6 @@ pub const trait Iterator { /// ``` #[inline] #[unstable(feature = "iter_next_chunk", issue = "98326")] - #[rustc_non_const_trait_method] fn next_chunk( &mut self, ) -> Result<[Self::Item; N], array::IntoIter> @@ -221,16 +221,18 @@ pub const trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_non_const_trait_method] fn count(self) -> usize where - Self: Sized, + Self: Sized + [const] Destruct, + Self::Item: [const] Destruct, { - self.fold( - 0, - #[rustc_inherit_overflow_checks] - |count, _| count + 1, - ) + // FIXME(const-hack): this should be a const closure + #[rustc_const_unstable(feature = "const_iter", issue = "92476")] + #[rustc_inherit_overflow_checks] + const fn plus_one(accum: usize, _elem: T) -> usize { + accum + 1 + } + self.fold(0, plus_one) } /// Consumes the iterator, returning the last element. @@ -254,13 +256,14 @@ pub const trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_non_const_trait_method] fn last(self) -> Option where - Self: Sized, + Self: Sized + [const] Destruct, + Self::Item: [const] Destruct, { + #[rustc_const_unstable(feature = "const_iter", issue = "92476")] #[inline] - fn some(_: Option, x: T) -> Option { + const fn some(_: Option, x: T) -> Option { Some(x) } @@ -302,32 +305,54 @@ pub const trait Iterator { /// ``` #[inline] #[unstable(feature = "iter_advance_by", issue = "77404")] - #[rustc_non_const_trait_method] - fn advance_by(&mut self, n: usize) -> Result<(), NonZero> { + fn advance_by(&mut self, n: usize) -> Result<(), NonZero> + where + Self::Item: [const] Destruct, + { /// Helper trait to specialize `advance_by` via `try_fold` for `Sized` iterators. - trait SpecAdvanceBy { + const trait SpecAdvanceBy { fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero>; } - impl SpecAdvanceBy for I { + #[rustc_const_unstable(feature = "const_iter", issue = "92476")] + impl const SpecAdvanceBy for I + where + I::Item: [const] Destruct, + { default fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero> { - for i in 0..n { + // FIXME(const-hack): this should be `for i in 0..n` + let mut i: usize = 0; + while i < n { if self.next().is_none() { // SAFETY: `i` is always less than `n`. return Err(unsafe { NonZero::new_unchecked(n - i) }); } + i += 1; } Ok(()) } } - impl SpecAdvanceBy for I { + #[rustc_const_unstable(feature = "const_iter", issue = "92476")] + impl const SpecAdvanceBy for I + where + I::Item: [const] Destruct, + { fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero> { + // FIXME(const-hack): this should be a const closure + #[rustc_const_unstable(feature = "const_iter", issue = "92476")] + const fn minus_one( + accum: NonZero, + _elem: T, + ) -> Option> { + NonZero::new(accum.get() - 1) + } + let Some(n) = NonZero::new(n) else { return Ok(()); }; - let res = self.try_fold(n, |n, _| NonZero::new(n.get() - 1)); + let res = self.try_fold(n, minus_one); match res { None => Ok(()), @@ -380,8 +405,10 @@ pub const trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_non_const_trait_method] - fn nth(&mut self, n: usize) -> Option { + fn nth(&mut self, n: usize) -> Option + where + Self::Item: [const] Destruct, + { self.advance_by(n).ok()?; self.next() } @@ -503,11 +530,10 @@ pub const trait Iterator { /// [`OsStr`]: ../../std/ffi/struct.OsStr.html #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_non_const_trait_method] fn chain(self, other: U) -> Chain where Self: Sized, - U: IntoIterator, + U: [const] IntoIterator, { Chain::new(self, other.into_iter()) } @@ -923,7 +949,6 @@ pub const trait Iterator { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "iter_filter"] - #[rustc_non_const_trait_method] fn filter

(self, predicate: P) -> Filter where Self: Sized, @@ -969,7 +994,6 @@ pub const trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_non_const_trait_method] fn filter_map(self, f: F) -> FilterMap where Self: Sized, @@ -1017,7 +1041,6 @@ pub const trait Iterator { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "enumerate_method"] - #[rustc_non_const_trait_method] fn enumerate(self) -> Enumerate where Self: Sized, @@ -1089,7 +1112,6 @@ pub const trait Iterator { /// [`next`]: Iterator::next #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_non_const_trait_method] fn peekable(self) -> Peekable where Self: Sized, @@ -1155,7 +1177,6 @@ pub const trait Iterator { #[inline] #[doc(alias = "drop_while")] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_non_const_trait_method] fn skip_while

(self, predicate: P) -> SkipWhile where Self: Sized, @@ -1234,7 +1255,6 @@ pub const trait Iterator { /// the iteration should stop, but wasn't placed back into the iterator. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_non_const_trait_method] fn take_while

(self, predicate: P) -> TakeWhile where Self: Sized, @@ -1323,7 +1343,6 @@ pub const trait Iterator { /// [`fuse`]: Iterator::fuse #[inline] #[stable(feature = "iter_map_while", since = "1.57.0")] - #[rustc_non_const_trait_method] fn map_while(self, predicate: P) -> MapWhile where Self: Sized, @@ -1353,7 +1372,6 @@ pub const trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_non_const_trait_method] fn skip(self, n: usize) -> Skip where Self: Sized, @@ -1426,7 +1444,6 @@ pub const trait Iterator { #[doc(alias = "limit")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_non_const_trait_method] fn take(self, n: usize) -> Take where Self: Sized, @@ -1474,7 +1491,6 @@ pub const trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_non_const_trait_method] fn scan(self, initial_state: St, f: F) -> Scan where Self: Sized, @@ -1598,7 +1614,6 @@ pub const trait Iterator { /// [`flat_map()`]: Iterator::flat_map #[inline] #[stable(feature = "iterator_flatten", since = "1.29.0")] - #[rustc_non_const_trait_method] fn flatten(self) -> Flatten where Self: Sized, @@ -1755,7 +1770,6 @@ pub const trait Iterator { /// ``` #[inline] #[unstable(feature = "iter_map_windows", issue = "87155")] - #[rustc_non_const_trait_method] fn map_windows(self, f: F) -> MapWindows where Self: Sized, @@ -1818,7 +1832,6 @@ pub const trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_non_const_trait_method] fn fuse(self) -> Fuse where Self: Sized, @@ -1903,7 +1916,6 @@ pub const trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_non_const_trait_method] fn inspect(self, f: F) -> Inspect where Self: Sized, @@ -2473,12 +2485,11 @@ pub const trait Iterator { /// ``` #[inline] #[stable(feature = "iterator_try_fold", since = "1.27.0")] - #[rustc_non_const_trait_method] fn try_fold(&mut self, init: B, mut f: F) -> R where Self: Sized, - F: FnMut(B, Self::Item) -> R, - R: Try, + F: [const] FnMut(B, Self::Item) -> R + [const] Destruct, + R: [const] Try, { let mut accum = init; while let Some(x) = self.next() { @@ -2540,7 +2551,10 @@ pub const trait Iterator { R: Try, { #[inline] - fn call(mut f: impl FnMut(T) -> R) -> impl FnMut((), T) -> R { + fn call(mut f: impl FnMut(T) -> R) -> impl FnMut((), T) -> R + where + R: Try, + { move |(), x| f(x) } @@ -2652,11 +2666,10 @@ pub const trait Iterator { #[doc(alias = "inject", alias = "foldl")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_non_const_trait_method] fn fold(mut self, init: B, mut f: F) -> B where - Self: Sized, - F: FnMut(B, Self::Item) -> B, + Self: Sized + [const] Destruct, + F: [const] FnMut(B, Self::Item) -> B + [const] Destruct, { let mut accum = init; while let Some(x) = self.next() { @@ -2690,11 +2703,10 @@ pub const trait Iterator { /// ``` #[inline] #[stable(feature = "iterator_fold_self", since = "1.51.0")] - #[rustc_non_const_trait_method] fn reduce(mut self, f: F) -> Option where - Self: Sized, - F: FnMut(Self::Item, Self::Item) -> Self::Item, + Self: Sized + [const] Destruct, + F: [const] FnMut(Self::Item, Self::Item) -> Self::Item + [const] Destruct, { let first = self.next()?; Some(self.fold(first, f)) @@ -2762,14 +2774,13 @@ pub const trait Iterator { /// ``` #[inline] #[unstable(feature = "iterator_try_reduce", issue = "87053")] - #[rustc_non_const_trait_method] fn try_reduce( &mut self, - f: impl FnMut(Self::Item, Self::Item) -> R, + f: impl [const] FnMut(Self::Item, Self::Item) -> R + [const] Destruct, ) -> ChangeOutputType> where Self: Sized, - R: Try>>, + R: [const] Try>>, { let first = match self.next() { Some(i) => i, @@ -3434,7 +3445,6 @@ pub const trait Iterator { #[inline] #[doc(alias = "reverse")] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_non_const_trait_method] fn rev(self) -> Rev where Self: Sized + DoubleEndedIterator, @@ -3503,7 +3513,6 @@ pub const trait Iterator { /// ``` #[stable(feature = "iter_copied", since = "1.36.0")] #[rustc_diagnostic_item = "iter_copied"] - #[rustc_non_const_trait_method] fn copied<'a, T>(self) -> Copied where T: Copy + 'a, @@ -3552,7 +3561,6 @@ pub const trait Iterator { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "iter_cloned"] - #[rustc_non_const_trait_method] fn cloned<'a, T>(self) -> Cloned where T: Clone + 'a, @@ -3584,10 +3592,9 @@ pub const trait Iterator { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - #[rustc_non_const_trait_method] fn cycle(self) -> Cycle where - Self: Sized + Clone, + Self: Sized + [const] Clone, { Cycle::new(self) } @@ -3628,7 +3635,6 @@ pub const trait Iterator { /// ``` #[track_caller] #[unstable(feature = "iter_array_chunks", issue = "100450")] - #[rustc_non_const_trait_method] fn array_chunks(self) -> ArrayChunks where Self: Sized, @@ -3665,11 +3671,10 @@ pub const trait Iterator { /// assert_eq!(sum, -0.0_f32); /// ``` #[stable(feature = "iter_arith", since = "1.11.0")] - #[rustc_non_const_trait_method] fn sum(self) -> S where Self: Sized, - S: Sum, + S: [const] Sum, { Sum::sum(self) } @@ -3698,11 +3703,10 @@ pub const trait Iterator { /// assert_eq!(factorial(5), 120); /// ``` #[stable(feature = "iter_arith", since = "1.11.0")] - #[rustc_non_const_trait_method] fn product

(self) -> P where Self: Sized, - P: Product, + P: [const] Product, { Product::product(self) } @@ -4199,7 +4203,7 @@ where F: FnMut(A::Item, B::Item) -> ControlFlow, { #[inline] - fn compare<'a, B, X, T>( + const fn compare<'a, B, X, T>( b: &'a mut B, mut f: impl FnMut(X, B::Item) -> ControlFlow + 'a, ) -> impl FnMut(X) -> ControlFlow> + 'a @@ -4211,7 +4215,6 @@ where Some(y) => f(x, y).map_break(ControlFlow::Break), } } - match a.try_for_each(compare(&mut b, f)) { ControlFlow::Continue(()) => ControlFlow::Continue(match b.next() { None => Ordering::Equal, diff --git a/src/ci/citool/src/jobs.rs b/src/ci/citool/src/jobs.rs index 245ab31fa6446..cc93761e9604e 100644 --- a/src/ci/citool/src/jobs.rs +++ b/src/ci/citool/src/jobs.rs @@ -200,12 +200,14 @@ fn validate_job_database(db: &JobDatabase) -> anyhow::Result<()> { equivalent_modulo_carve_out(pr_job, auto_job)?; } - // Auto CI jobs must all "fail-fast" to avoid wasting Auto CI resources. For instance, `tidy`. + // Auto CI should "fail-fast" to avoid wasting Auto CI resources. + // However, some experimental auto jobs can be made optional, for example if we are unsure about + // their flakiness. Those have to be prefixed with `optional-`. for auto_job in &db.auto_jobs { - if auto_job.continue_on_error == Some(true) { + if auto_job.continue_on_error == Some(true) && !auto_job.name.starts_with("optional-") { return Err(anyhow!( - "Auto job `{}` cannot have `continue_on_error: true`", - auto_job.name + "Auto job `{job}` cannot have `continue_on_error: true`. If the job should be optional, name it `optional-{job}`.", + job = auto_job.name )); } } diff --git a/src/ci/docker/host-x86_64/optional-x86_64-gnu-parallel-frontend/Dockerfile b/src/ci/docker/host-x86_64/optional-x86_64-gnu-parallel-frontend/Dockerfile new file mode 100644 index 0000000000000..8f7c7ebe35559 --- /dev/null +++ b/src/ci/docker/host-x86_64/optional-x86_64-gnu-parallel-frontend/Dockerfile @@ -0,0 +1,36 @@ +FROM ubuntu:22.04 + +ARG DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get install -y --no-install-recommends \ + g++ \ + make \ + ninja-build \ + file \ + curl \ + ca-certificates \ + python3 \ + git \ + cmake \ + sudo \ + gdb \ + libssl-dev \ + pkg-config \ + xz-utils \ + mingw-w64 \ + zlib1g-dev \ + libzstd-dev \ + && rm -rf /var/lib/apt/lists/* + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +ENV RUST_CONFIGURE_ARGS \ + --build=x86_64-unknown-linux-gnu \ + --enable-sanitizers \ + --enable-profiler \ + --enable-compiler-docs \ + --set llvm.libzstd=true + +# Build the toolchain with multiple parallel frontend threads and then run tests +# Tests are still compiled serially at the moment (intended to be changed in follow-ups). +ENV SCRIPT python3 ../x.py --stage 2 test --set rust.parallel-frontend-threads=4 diff --git a/src/ci/docker/host-x86_64/pr-check-1/Dockerfile b/src/ci/docker/host-x86_64/pr-check-1/Dockerfile index c1742720f7789..a595a079b48f1 100644 --- a/src/ci/docker/host-x86_64/pr-check-1/Dockerfile +++ b/src/ci/docker/host-x86_64/pr-check-1/Dockerfile @@ -39,7 +39,7 @@ COPY host-x86_64/pr-check-1/validate-toolstate.sh /scripts/ # Check library crates on all tier 1 targets. # We disable optimized compiler built-ins because that requires a C toolchain for the target. # We also skip the x86_64-unknown-linux-gnu target as it is well-tested by other jobs. -ENV SCRIPT \ +ENV SCRIPT=" \ # Check some tools that aren't included in `x check` by default, to # ensure that maintainers can still do check builds locally. python3 ../x.py check \ @@ -58,4 +58,4 @@ ENV SCRIPT \ python3 ../x.py check --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \ /scripts/validate-toolstate.sh && \ reuse --include-submodules lint && \ - python3 ../x.py test collect-license-metadata + python3 ../x.py test collect-license-metadata" diff --git a/src/ci/docker/host-x86_64/pr-check-2/Dockerfile b/src/ci/docker/host-x86_64/pr-check-2/Dockerfile index 885bf0b30b18c..6b843a6247e89 100644 --- a/src/ci/docker/host-x86_64/pr-check-2/Dockerfile +++ b/src/ci/docker/host-x86_64/pr-check-2/Dockerfile @@ -30,8 +30,7 @@ ENV RUST_CONFIGURE_ARGS="--set rust.validate-mir-opts=3" COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh -ENV SCRIPT \ - python3 ../x.py check && \ +ENV SCRIPT="python3 ../x.py check && \ python3 ../x.py clippy ci --stage 2 && \ python3 ../x.py test --stage 1 core alloc std test proc_macro && \ # Elsewhere, we run all tests for the host. A number of codegen tests are sensitive to the target pointer @@ -48,4 +47,4 @@ ENV SCRIPT \ RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc library/test --stage 1 && \ # The BOOTSTRAP_TRACING flag is added to verify whether the # bootstrap process compiles successfully with this flag enabled. - BOOTSTRAP_TRACING=1 python3 ../x.py --help + BOOTSTRAP_TRACING=1 python3 ../x.py --help" diff --git a/src/ci/docker/host-x86_64/tidy/Dockerfile b/src/ci/docker/host-x86_64/tidy/Dockerfile index 133192e8ac214..e84d61e0b99cc 100644 --- a/src/ci/docker/host-x86_64/tidy/Dockerfile +++ b/src/ci/docker/host-x86_64/tidy/Dockerfile @@ -39,5 +39,5 @@ COPY host-x86_64/pr-check-1/validate-toolstate.sh /scripts/ # NOTE: intentionally uses python2 for x.py so we can test it still works. # validate-toolstate only runs in our CI, so it's ok for it to only support python3. -ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test \ - src/tools/tidy tidyselftest --extra-checks=py,cpp,js,spellcheck +ENV SCRIPT="TIDY_PRINT_DIFF=1 python2.7 ../x.py test \ + src/tools/tidy tidyselftest --extra-checks=py,cpp,js,spellcheck" diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 0687d142a3504..563083cd450bc 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -348,6 +348,11 @@ auto: - name: x86_64-gnu <<: *job-linux-4c + - name: optional-x86_64-gnu-parallel-frontend + # This test can be flaky, so do not cancel CI if it fails, for now. + continue_on_error: true + <<: *job-linux-4c + - name: x86_64-gnu-gcc doc_url: https://rustc-dev-guide.rust-lang.org/tests/codegen-backend-tests/cg_gcc.html <<: *job-linux-4c diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index b6e1b2bc55df4..db9492636f6ac 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -c78a29473a68f07012904af11c92ecffa68fcc75 +eda4fc7733ee89e484d7120cafbd80dcb2fce66e diff --git a/src/doc/rustc-dev-guide/src/autodiff/installation.md b/src/doc/rustc-dev-guide/src/autodiff/installation.md index e05fdc1160f2f..6b66a9dcb2d5f 100644 --- a/src/doc/rustc-dev-guide/src/autodiff/installation.md +++ b/src/doc/rustc-dev-guide/src/autodiff/installation.md @@ -1,6 +1,50 @@ # Installation -In the near future, `std::autodiff` should become available in nightly builds for users. As a contributor however, you will still need to build rustc from source. Please be aware that the msvc target is not supported at the moment, all other tier 1 targets should work. Please open an issue if you encounter any problems on a supported tier 1 target, or if you successfully build this project on a tier2/tier3 target. +In the near future, `std::autodiff` should become available for users via rustup. As a rustc/enzyme/autodiff contributor however, you will still need to build rustc from source. +For the meantime, you can download up-to-date builds to enable `std::autodiff` on your latest nightly toolchain, if you are using either of: +**Linux**, with `x86_64-unknown-linux-gnu` or `aarch64-unknown-linux-gnu` +**Windows**, with `x86_64-llvm-mingw` or `aarch64-llvm-mingw` + +You can also download slightly outdated builds for **Apple** (aarch64-apple), which should generally work for now. + +If you need any other platform, you can build rustc including autodiff from source. Please open an issue if you want to help enabling automatic builds for your prefered target. + +## Installation guide + +If you want to use `std::autodiff` and don't plan to contribute PR's to the project, then we recommend to just use your existing nightly installation and download the missing component. In the future, rustup will be able to do it for you. +For now, you'll have to manually download and copy it. + +1) On our github repository, find the last merged PR: [`Repo`] +2) Scroll down to the lower end of the PR, where you'll find a rust-bors message saying `Test successful` with a `CI` link. +3) Click on the `CI` link, and grep for your target. E.g. `dist-x86_64-linux` or `dist-aarch64-llvm-mingw` and click `Load summary`. +4) Under the `CI artifacts` section, find the `enzyme-nightly` artifact, download, and unpack it. +5) Copy the artifact (libEnzyme-22.so for linux, libEnzyme-22.dylib for apple, etc.), which should be in a folder named `enzyme-preview`, to your rust toolchain directory. E.g. for linux: `cp ~/Downloads/enzyme-nightly-x86_64-unknown-linux-gnu/enzyme-preview/lib/rustlib/x86_64-unknown-linux-gnu/lib/libEnzyme-22.so ~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib` + +Apple support was temporarily reverted, due to downstream breakages. If you want to download autodiff for apple, please look at the artifacts from this [`run`]. + +## Installation guide for Nix user. + +This setup was recommended by a nix and autodiff user. It uses [`Overlay`]. Please verify for yourself if you are comfortable using that repository. +In that case you might use the following nix configuration to get a rustc that supports `std::autodiff`. +```nix +{ + enzymeLib = pkgs.fetchzip { + url = "https://ci-artifacts.rust-lang.org/rustc-builds/ec818fda361ca216eb186f5cf45131bd9c776bb4/enzyme-nightly-x86_64-unknown-linux-gnu.tar.xz"; + sha256 = "sha256-Rnrop44vzS+qmYNaRoMNNMFyAc3YsMnwdNGYMXpZ5VY="; + }; + + rustToolchain = pkgs.symlinkJoin { + name = "rust-with-enzyme"; + paths = [pkgs.rust-bin.nightly.latest.default]; + nativeBuildInputs = [pkgs.makeWrapper]; + postBuild = '' + libdir=$out/lib/rustlib/x86_64-unknown-linux-gnu/lib + cp ${enzymeLib}/enzyme-preview/lib/rustlib/x86_64-unknown-linux-gnu/lib/libEnzyme-22.so $libdir/ + wrapProgram $out/bin/rustc --add-flags "--sysroot $out" + ''; + }; +} +``` ## Build instructions @@ -87,3 +131,6 @@ ninja ``` This will build Enzyme, and you can find it in `Enzyme/enzyme/build/lib/Enzyme.so`. (Endings might differ based on your OS). +[`Repo`]: https://github.com/rust-lang/rust/ +[`run`]: https://github.com/rust-lang/rust/pull/153026#issuecomment-3950046599 +[`Overlay`]: https://github.com/oxalica/rust-overlay diff --git a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md index 3d0e130b6aaa6..56fa49ef2a2e4 100644 --- a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md +++ b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md @@ -6,7 +6,12 @@ Rust supports building against multiple LLVM versions: * Tip-of-tree for the current LLVM development branch is usually supported within a few days. PRs for such fixes are tagged with `llvm-main`. * The latest released major version is always supported. -* The one or two preceding major versions are usually supported. +* The one or two preceding major versions are usually supported in the sense that they are expected + to build successfully and pass most tests. + However, fixes for miscompilations often do not get + backported to past LLVM versions, so using rustc with older versions of LLVM comes with an + increased risk of soundness bugs. + We strongly recommend using the latest version of LLVM. By default, Rust uses its own fork in the [rust-lang/llvm-project repository]. This fork is based on a `release/$N.x` branch of the upstream project, where diff --git a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md index fc8fe402bfa9e..317b7c2564cbc 100644 --- a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md +++ b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md @@ -110,7 +110,6 @@ Also, using `x` rather than `x.py` is recommended as: Notice that this is not absolute. For instance, using Nushell in VSCode on Win10, typing `x` or `./x` still opens `x.py` in an editor rather than invoking the program. -:) In the rest of this guide, we use `x` rather than `x.py` directly. The following command: diff --git a/src/doc/rustc-dev-guide/src/conventions.md b/src/doc/rustc-dev-guide/src/conventions.md index 0e08ef9042d1e..0440fb0c5e736 100644 --- a/src/doc/rustc-dev-guide/src/conventions.md +++ b/src/doc/rustc-dev-guide/src/conventions.md @@ -139,6 +139,8 @@ if foo { } ``` +If you want to leave a note in the codebase, use `// FIXME` instead. + ## Using crates from crates.io diff --git a/src/doc/rustc-dev-guide/src/diagnostics/translation.md b/src/doc/rustc-dev-guide/src/diagnostics/translation.md index cf95727e2a673..a22ede5e9c3ba 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/translation.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/translation.md @@ -31,8 +31,7 @@ There are two ways of writing translatable diagnostics: ("Simple" diagnostics being those that don't require a lot of logic in deciding to emit subdiagnostics and can therefore be represented as diagnostic structs). See [the diagnostic and subdiagnostic structs documentation](./diagnostic-structs.md). -2. Using typed identifiers with `Diag` APIs (in - `Diagnostic` or `Subdiagnostic` implementations). +2. Using typed identifiers with `Diag` APIs (in `Diagnostic` or `Subdiagnostic` implementations). When adding or changing a translatable diagnostic, you don't need to worry about the translations. diff --git a/src/doc/rustc-dev-guide/src/feature-gate-check.md b/src/doc/rustc-dev-guide/src/feature-gate-check.md index 59e50837c52e2..038a14ac070e1 100644 --- a/src/doc/rustc-dev-guide/src/feature-gate-check.md +++ b/src/doc/rustc-dev-guide/src/feature-gate-check.md @@ -8,7 +8,7 @@ nightly-only `#![feature(...)]` opt-in. This chapter documents the implementation of feature gating: where gates are defined, how they are enabled, and how usage is verified. - + ## Feature Definitions diff --git a/src/doc/rustc-dev-guide/src/git.md b/src/doc/rustc-dev-guide/src/git.md index bf31e79a9a154..faa2d8f2a3a21 100644 --- a/src/doc/rustc-dev-guide/src/git.md +++ b/src/doc/rustc-dev-guide/src/git.md @@ -383,6 +383,13 @@ Both the upside and downside of this is that it simplifies the history. On the one hand, you lose track of the steps in which changes were made, but the history becomes easier to work with. +The easiest way to squash your commits in a PR on the `rust-lang/rust` repository is to use the `@bors squash` command in a comment on the PR. +By default, [bors] combines all commit messages of the PR into the squashed commit message. +To customize the commit message, use `@bors squash msg=`. + + +If you want to squash commits using local git operations, read on below. + If there are no conflicts and you are just squashing to clean up the history, use `git rebase --interactive --keep-base main`. This keeps the fork point of your PR the same, making it easier to review the diff of what happened @@ -410,11 +417,6 @@ because they only represent "fixups" and not real changes. For example, `git rebase --interactive HEAD~2` will allow you to edit the two commits only. -For pull requests in `rust-lang/rust`, you can ask [bors] to squash by commenting -`@bors squash` on the PR. -By default, [bors] combines all commit messages in the PR. -To customize the commit message, use `@bors squash [msg|message=]`. - [bors]: https://github.com/rust-lang/bors ### `git range-diff` diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md index 5ab2ab428e811..1621d79db247a 100644 --- a/src/doc/rustc-dev-guide/src/query.md +++ b/src/doc/rustc-dev-guide/src/query.md @@ -90,7 +90,7 @@ dependencies of the local crate) Note that what determines the crate that a query is targeting is not the *kind* of query, but the *key*. For example, when you invoke `tcx.type_of(def_id)`, that could be a local query or an external query, depending on what crate the `def_id` -is referring to (see the [`self::keys::Key`][Key] trait for more information on how that works). +is referring to (see the [`self::keys::QueryKey`][QueryKey] trait for more information on how that works). Providers always have the same signature: @@ -308,7 +308,7 @@ Let's go over these elements one by one: Also used as the name of a struct (`ty::queries::type_of`) that will be generated to represent this query. - **Query key type:** the type of the argument to this query. - This type must implement the [`ty::query::keys::Key`][Key] trait, which + This type must implement the [`ty::query::keys::QueryKey`][QueryKey] trait, which defines (for example) how to map it to a crate, and so forth. - **Result type of query:** the type produced by this query. This type should (a) not use `RefCell` or other interior mutability and (b) be @@ -317,7 +317,7 @@ Let's go over these elements one by one: - **Query modifiers:** various flags and options that customize how the query is processed (mostly with respect to [incremental compilation][incrcomp]). -[Key]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/query/keys/trait.Key.html +[QueryKey]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/query/keys/trait.QueryKey.html [incrcomp]: queries/incremental-compilation-in-detail.html#query-modifiers So, to add a query: diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index 6b63f68b29ee9..5161194492e6c 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -109,6 +109,12 @@ The live results can be seen on [the GitHub Actions workflows page]. At any given time, at most a single `auto` build is being executed. Find out more in [Merging PRs serially with bors](#merging-prs-serially-with-bors). +Normally, when an auto job fails, the whole CI workflow immediately ends. However, it can be useful to +create auto jobs that are "non-blocking", or optional, to test them on CI for some time before blocking +merges on them. This can be useful if those jobs can be flaky. + +To do that, prefix such a job with `optional-`, and set `continue_on_error: true` for it in [`jobs.yml`]. + [platform tiers]: https://forge.rust-lang.org/release/platform-support.html#rust-platform-support [auto]: https://github.com/rust-lang/rust/tree/automation/bors/auto diff --git a/src/doc/rustc-dev-guide/src/tracing.md b/src/doc/rustc-dev-guide/src/tracing.md index 151670d089970..78a0fe4af2ff2 100644 --- a/src/doc/rustc-dev-guide/src/tracing.md +++ b/src/doc/rustc-dev-guide/src/tracing.md @@ -14,8 +14,8 @@ of `tracing-subscriber`](https://docs.rs/tracing-subscriber/0.2.24/tracing_subsc ## Environment variables -This is an overview of the environment variables rustc accepts to customize -its tracing output. The definition of these can mostly be found in `compiler/rustc_log/src/lib.rs`. +This is an overview of the environment variables rustc accepts to customize its tracing output. +The definition of these can mostly be found in `compiler/rustc_log/src/lib.rs`. | Name | Usage | | ------------------------- | ----------------------------------------------------------------------------------------------------------------------- | diff --git a/tests/codegen-units/item-collection/opaque-return-impls.rs b/tests/codegen-units/item-collection/opaque-return-impls.rs index 484fbe7fe62f1..1425a51af73b0 100644 --- a/tests/codegen-units/item-collection/opaque-return-impls.rs +++ b/tests/codegen-units/item-collection/opaque-return-impls.rs @@ -73,15 +73,17 @@ pub fn foo3() -> Box> { } //~ MONO_ITEM fn ::spec_advance_by -//~ MONO_ITEM fn ::spec_advance_by::{closure#0} //~ MONO_ITEM fn ::advance_by +//~ MONO_ITEM fn ::try_fold::, fn(std::num::NonZero, usize) -> std::option::Option> {::spec_advance_by::minus_one::}, std::option::Option>> @@ opaque_return_impls-cgu.0[External] +//~ MONO_ITEM fn ::spec_advance_by::minus_one:: @@ opaque_return_impls-cgu.0[External] +//~ MONO_ITEM fn , usize) -> std::option::Option> {::spec_advance_by::minus_one::} as std::ops::FnMut<(std::num::NonZero, usize)>>::call_mut - shim(fn(std::num::NonZero, usize) -> std::option::Option> {::spec_advance_by::minus_one::}) @@ opaque_return_impls-cgu.0[Internal] //~ MONO_ITEM fn ::next //~ MONO_ITEM fn ::nth //~ MONO_ITEM fn ::size_hint -//~ MONO_ITEM fn ::try_fold::, {closure@::spec_advance_by::{closure#0}}, std::option::Option>> //~ MONO_ITEM fn > as std::ops::FromResidual>>::from_residual //~ MONO_ITEM fn > as std::ops::Try>::branch //~ MONO_ITEM fn > as std::ops::Try>::from_output + //~ MONO_ITEM fn foo3 //~ MONO_ITEM fn std::boxed::Box::::new //~ MONO_ITEM fn Counter::new diff --git a/tests/run-make/target-cpu-native/foo.rs b/tests/run-make/target-cpu-native/foo.rs index f328e4d9d04c3..5abcd25abc3f3 100644 --- a/tests/run-make/target-cpu-native/foo.rs +++ b/tests/run-make/target-cpu-native/foo.rs @@ -1 +1,9 @@ fn main() {} + +// This forces explicit emission of a +neon target feature on targets +// where it is implied by the target-cpu, like aarch64-apple-darwin. +// This is a regression test for #153397. +#[cfg(target_feature = "neon")] +#[target_feature(enable = "neon")] +#[unsafe(no_mangle)] +pub fn with_neon() {} diff --git a/tests/run-make/target-cpu-native/rmake.rs b/tests/run-make/target-cpu-native/rmake.rs index 7b7974f309789..5791bf01bba2b 100644 --- a/tests/run-make/target-cpu-native/rmake.rs +++ b/tests/run-make/target-cpu-native/rmake.rs @@ -8,7 +8,12 @@ use run_make_support::{run, rustc}; fn main() { - let out = rustc().input("foo.rs").arg("-Ctarget-cpu=native").run().stderr_utf8(); + let out = rustc() + .input("foo.rs") + .arg("-Ctarget-cpu=native") + .arg("-Zverify-llvm-ir") + .run() + .stderr_utf8(); run("foo"); // There should be zero warnings emitted - the bug would cause "unknown CPU `native`" // to be printed out. diff --git a/tests/ui/async-await/async-closures/is-fn.rs b/tests/ui/async-await/async-closures/is-fn.rs index 45c2b6ae342b6..1d546cd44b496 100644 --- a/tests/ui/async-await/async-closures/is-fn.rs +++ b/tests/ui/async-await/async-closures/is-fn.rs @@ -9,11 +9,11 @@ use std::future::Future; extern crate block_on; -// Check that closures that don't capture any state may implement `Fn`. +// Check that async closures that don't capture any state may implement `Fn`. fn main() { block_on::block_on(async { - async fn call_once(x: impl FnOnce(&'static str) -> F) -> F::Output { + async fn call_once(x: impl Fn(&'static str) -> F) -> F::Output { x("hello, world").await } call_once(async |x: &'static str| { diff --git a/tests/ui/feature-gates/incomplete-features.rs b/tests/ui/feature-gates/incomplete-features.rs new file mode 100644 index 0000000000000..7f8f1a46ebcb0 --- /dev/null +++ b/tests/ui/feature-gates/incomplete-features.rs @@ -0,0 +1,13 @@ +//! Make sure that incomplete features emit the `incomplete_features` lint. + +// gate-test-test_incomplete_feature + +//@ check-pass +//@ revisions: warn expect + +#![cfg_attr(warn, warn(incomplete_features))] +#![cfg_attr(expect, expect(incomplete_features))] + +#![feature(test_incomplete_feature)] //[warn]~ WARN the feature `test_incomplete_feature` is incomplete + +fn main() {} diff --git a/tests/ui/feature-gates/incomplete-features.warn.stderr b/tests/ui/feature-gates/incomplete-features.warn.stderr new file mode 100644 index 0000000000000..7dda9f3648da5 --- /dev/null +++ b/tests/ui/feature-gates/incomplete-features.warn.stderr @@ -0,0 +1,14 @@ +warning: the feature `test_incomplete_feature` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/incomplete-features.rs:11:12 + | +LL | #![feature(test_incomplete_feature)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/incomplete-features.rs:8:24 + | +LL | #![cfg_attr(warn, warn(incomplete_features))] + | ^^^^^^^^^^^^^^^^^^^ + +warning: 1 warning emitted + diff --git a/tests/ui/parallel-rustc/fn-sig-cycle-ice-153391.rs b/tests/ui/parallel-rustc/fn-sig-cycle-ice-153391.rs new file mode 100644 index 0000000000000..0108ada8c08c3 --- /dev/null +++ b/tests/ui/parallel-rustc/fn-sig-cycle-ice-153391.rs @@ -0,0 +1,18 @@ +// Regression test for #153391. +// +//@ edition:2024 +//@ compile-flags: -Z threads=16 +//@ compare-output-by-lines +//@ ignore-test (#142063) + +trait A { + fn g() -> B; + //~^ ERROR expected a type, found a trait +} + +trait B { + fn bar(&self, x: &A); + //~^ ERROR expected a type, found a trait +} + +fn main() {} diff --git a/tests/ui/parallel-rustc/fn-sig-cycle-ice-153391.stderr b/tests/ui/parallel-rustc/fn-sig-cycle-ice-153391.stderr new file mode 100644 index 0000000000000..4d348cf22f4ef --- /dev/null +++ b/tests/ui/parallel-rustc/fn-sig-cycle-ice-153391.stderr @@ -0,0 +1,31 @@ +error[E0782]: expected a type, found a trait + --> $DIR/fn-sig-cycle-ice-153391.rs:8:15 + | +LL | fn g() -> B; + | ^ + | +help: `B` is dyn-incompatible, use `impl B` to return an opaque type, as long as you return a single underlying type + | +LL | fn g() -> impl B; + | ++++ + +error[E0782]: expected a type, found a trait + --> $DIR/fn-sig-cycle-ice-153391.rs:13:23 + | +LL | fn bar(&self, x: &A); + | ^ + | + = note: `A` is dyn-incompatible, otherwise a trait object could be used +help: use a new generic type parameter, constrained by `A` + | +LL - fn bar(&self, x: &A); +LL + fn bar(&self, x: &T); + | +help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference + | +LL | fn bar(&self, x: &impl A); + | ++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0782`. diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs index 48547c019d628..80bc8da519fca 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.rs +++ b/tests/ui/typeck/typeck_type_placeholder_item.rs @@ -239,5 +239,4 @@ fn evens_squared(n: usize) -> _ { const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); //~^ ERROR the placeholder -//~| ERROR cannot call non-const -//~| ERROR cannot call non-const +//~| ERROR the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index 2772d55f953a8..129cf9b50c10d 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -587,17 +587,20 @@ LL - fn evens_squared(n: usize) -> _ { LL + fn evens_squared(n: usize) -> impl Iterator { | -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants - --> $DIR/typeck_type_placeholder_item.rs:240:10 +error[E0277]: the trait bound `std::ops::Range<{integer}>: const Iterator` is not satisfied + --> $DIR/typeck_type_placeholder_item.rs:240:15 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^ not allowed in type signatures + | ^^^^^ ------ required by a bound introduced by this call | -note: however, the inferred type `Map, {closure@typeck_type_placeholder_item.rs:240:29}>, {closure@typeck_type_placeholder_item.rs:240:49}>` cannot be named - --> $DIR/typeck_type_placeholder_item.rs:240:14 +note: trait `Iterator` is implemented but not `const` + --> $SRC_DIR/core/src/iter/range.rs:LL:COL + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:240:10 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:40:24 @@ -678,23 +681,7 @@ LL | fn map(_: fn() -> Option<&'static T>) -> Option { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants -error[E0015]: cannot call non-const method ` as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:240:29: 240:32}>` in constants - --> $DIR/typeck_type_placeholder_item.rs:240:22 - | -LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants - -error[E0015]: cannot call non-const method `, {closure@$DIR/typeck_type_placeholder_item.rs:240:29: 240:32}> as Iterator>::map::` in constants - --> $DIR/typeck_type_placeholder_item.rs:240:45 - | -LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^^^^^^^^^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants - -error: aborting due to 83 previous errors +error: aborting due to 82 previous errors -Some errors have detailed explanations: E0015, E0046, E0121, E0282, E0403. +Some errors have detailed explanations: E0015, E0046, E0121, E0277, E0282, E0403. For more information about an error, try `rustc --explain E0015`.