Auto merge of #151875 - JonathanBrouwer:rollup-OPCJQtC, r=JonathanBrouwer

Rollup of 2 pull requests

Successful merges:

 - rust-lang/rust#151281 (constify `Iterator`, take IV)
 - rust-lang/rust#151873 (resolve: Remove `force` parameter from `resolve_ident_in_scope`)
This commit is contained in:
bors 2026-01-30 22:15:51 +00:00
commit 44e34e1ac6
29 changed files with 286 additions and 85 deletions

View file

@ -388,3 +388,15 @@ impl<S: Stage> CombineAttributeParser<S> for RustcLayoutParser {
result
}
}
pub(crate) struct RustcNonConstTraitMethodParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcNonConstTraitMethodParser {
const PATH: &'static [Symbol] = &[sym::rustc_non_const_trait_method];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::Method(MethodKind::Trait { body: false })),
]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNonConstTraitMethod;
}

View file

@ -79,9 +79,9 @@ use crate::attributes::rustc_internal::{
RustcLayoutScalarValidRangeStartParser, RustcLegacyConstGenericsParser,
RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser, RustcLintQueryInstabilityParser,
RustcLintUntrackedQueryInformationParser, RustcMainParser, RustcMustImplementOneOfParser,
RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, RustcNounwindParser,
RustcObjectLifetimeDefaultParser, RustcOffloadKernelParser, RustcScalableVectorParser,
RustcSimdMonomorphizeLaneLimitParser,
RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser,
RustcNonConstTraitMethodParser, RustcNounwindParser, RustcObjectLifetimeDefaultParser,
RustcOffloadKernelParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser,
};
use crate::attributes::semantics::MayDangleParser;
use crate::attributes::stability::{
@ -305,6 +305,7 @@ attribute_parsers!(
Single<WithoutArgs<RustcMainParser>>,
Single<WithoutArgs<RustcNeverReturnsNullPointerParser>>,
Single<WithoutArgs<RustcNoImplicitAutorefsParser>>,
Single<WithoutArgs<RustcNonConstTraitMethodParser>>,
Single<WithoutArgs<RustcNounwindParser>>,
Single<WithoutArgs<RustcOffloadKernelParser>>,
Single<WithoutArgs<RustcPassIndirectlyInNonRusticAbisParser>>,

View file

@ -774,16 +774,16 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// Attempting to call a trait method?
if let Some(trait_did) = tcx.trait_of_assoc(callee) {
// We can't determine the actual callee here, so we have to do different checks
// than usual.
// We can't determine the actual callee (the underlying impl of the trait) here, so we have
// to do different checks than usual.
trace!("attempting to call a trait method");
let trait_is_const = tcx.is_const_trait(trait_did);
let is_const = tcx.constness(callee) == hir::Constness::Const;
// Only consider a trait to be const if the const conditions hold.
// Otherwise, it's really misleading to call something "conditionally"
// const when it's very obviously not conditionally const.
if trait_is_const && has_const_conditions == Some(ConstConditionsHold::Yes) {
if is_const && has_const_conditions == Some(ConstConditionsHold::Yes) {
// Trait calls are always conditionally-const.
self.check_op(ops::ConditionallyConstCall {
callee,

View file

@ -1,7 +1,8 @@
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{
Constness, ExprKind, ForeignItemKind, ImplItem, ImplItemImplKind, ImplItemKind, Item, ItemKind,
Node, TraitItem, TraitItemKind, VariantData,
Node, TraitItem, TraitItemKind, VariantData, find_attr,
};
use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
@ -36,7 +37,13 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Constness {
Constness::NotConst => tcx.constness(tcx.local_parent(def_id)),
}
}
Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(..), .. }) => tcx.trait_def(tcx.local_parent(def_id)).constness,
Node::TraitItem(ti @ TraitItem { kind: TraitItemKind::Fn(..), .. }) => {
if find_attr!(tcx.hir_attrs(ti.hir_id()), AttributeKind::RustcNonConstTraitMethod) {
Constness::NotConst
} else {
tcx.trait_def(tcx.local_parent(def_id)).constness
}
}
_ => {
tcx.dcx().span_bug(
tcx.def_span(def_id),

View file

@ -1329,6 +1329,12 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
"`#[rustc_has_incoherent_inherent_impls]` allows the addition of incoherent inherent impls for \
the given type by annotating all impl items with `#[rustc_allow_incoherent_impl]`"
),
rustc_attr!(
rustc_non_const_trait_method, AttributeType::Normal, template!(Word),
ErrorFollowing, EncodeCrossCrate::No,
"`#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods \
as non-const to allow large traits an easier transition to const"
),
BuiltinAttribute {
name: sym::rustc_diagnostic_item,

View file

@ -1096,6 +1096,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_no_implicit_autorefs]`
RustcNoImplicitAutorefs,
/// Represents `#[rustc_non_const_trait_method]`.
RustcNonConstTraitMethod,
/// Represents `#[rustc_nounwind]`
RustcNounwind,

View file

@ -124,6 +124,7 @@ impl AttributeKind {
RustcMustImplementOneOf { .. } => No,
RustcNeverReturnsNullPointer => Yes,
RustcNoImplicitAutorefs => Yes,
RustcNonConstTraitMethod => No, // should be reported via other queries like `constness`
RustcNounwind => No,
RustcObjcClass { .. } => No,
RustcObjcSelector { .. } => No,

View file

@ -218,7 +218,7 @@ fn compare_method_predicate_entailment<'tcx>(
trait_m_predicates.instantiate_own(tcx, trait_to_impl_args).map(|(predicate, _)| predicate),
);
let is_conditionally_const = tcx.is_conditionally_const(impl_def_id);
let is_conditionally_const = tcx.is_conditionally_const(impl_m.def_id);
if is_conditionally_const {
// Augment the hybrid param-env with the const conditions
// of the impl header and the trait method.

View file

@ -2086,8 +2086,16 @@ impl<'tcx> TyCtxt<'tcx> {
DefKind::Impl { of_trait: false } => {
self.constness(def_id) == hir::Constness::Const
}
DefKind::Impl { of_trait: true } | DefKind::Trait => {
self.is_conditionally_const(parent_def_id)
DefKind::Impl { of_trait: true } => {
let Some(trait_method_did) = self.trait_item_of(def_id) else {
return false;
};
self.constness(trait_method_did) == hir::Constness::Const
&& self.is_conditionally_const(parent_def_id)
}
DefKind::Trait => {
self.constness(def_id) == hir::Constness::Const
&& self.is_conditionally_const(parent_def_id)
}
_ => bug!("unexpected parent item of associated fn: {parent_def_id:?}"),
}

View file

@ -310,6 +310,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::RustcMain
| AttributeKind::RustcNeverReturnsNullPointer
| AttributeKind::RustcNoImplicitAutorefs
| AttributeKind::RustcNonConstTraitMethod
| AttributeKind::RustcNounwind
| AttributeKind::RustcObjcClass { .. }
| AttributeKind::RustcObjcSelector { .. }
@ -335,7 +336,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::Used { .. }
| AttributeKind::WindowsSubsystem(..)
// tidy-alphabetical-end
) => { /* do nothing */ }
Attribute::Unparsed(attr_item) => {
style = Some(attr_item.style);

View file

@ -1709,7 +1709,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::All(ns),
parent_scope,
None,
false,
None,
None,
) else {
@ -2546,7 +2545,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::All(ns_to_try),
parent_scope,
None,
false,
ignore_decl,
ignore_import,
)
@ -2650,7 +2648,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::All(ValueNS),
parent_scope,
None,
false,
ignore_decl,
ignore_import,
) {

View file

@ -350,7 +350,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::Module(ns, module),
parent_scope,
finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
finalize.is_some(),
ignore_decl,
None,
)
@ -368,7 +367,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::All(ns),
parent_scope,
finalize,
finalize.is_some(),
ignore_decl,
None,
)
@ -396,12 +394,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
scope_set: ScopeSet<'ra>,
parent_scope: &ParentScope<'ra>,
finalize: Option<Finalize>,
force: bool,
ignore_decl: Option<Decl<'ra>>,
ignore_import: Option<Import<'ra>>,
) -> Result<Decl<'ra>, Determinacy> {
assert!(force || finalize.is_none()); // `finalize` implies `force`
// Make sure `self`, `super` etc produce an error when passed to here.
if !matches!(scope_set, ScopeSet::Module(..)) && orig_ident.is_path_segment_keyword() {
return Err(Determinacy::Determined);
@ -451,7 +446,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
parent_scope,
// Shadowed decls don't need to be marked as used or non-speculatively loaded.
if innermost_results.is_empty() { finalize } else { None },
force,
ignore_decl,
ignore_import,
) {
@ -509,7 +503,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// Scope visiting walked all the scopes and maybe found something in one of them.
match innermost_results.first() {
Some(&(decl, ..)) => Ok(decl),
None => Err(Determinacy::determined(determinacy == Determinacy::Determined || force)),
None => Err(determinacy),
}
}
@ -523,7 +517,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
scope_set: ScopeSet<'ra>,
parent_scope: &ParentScope<'ra>,
finalize: Option<Finalize>,
force: bool,
ignore_decl: Option<Decl<'ra>>,
ignore_import: Option<Import<'ra>>,
) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {
@ -546,7 +539,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
match self.reborrow().resolve_derive_macro_path(
derive,
parent_scope,
force,
false,
ignore_import,
) {
Ok((Some(ext), _)) => {
@ -617,11 +610,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Ok(decl)
}
Err(ControlFlow::Continue(determinacy)) => Err(determinacy),
Err(ControlFlow::Break(determinacy)) => {
return Err(ControlFlow::Break(Determinacy::determined(
determinacy == Determinacy::Determined || force,
)));
}
Err(ControlFlow::Break(..)) => return decl,
}
}
Scope::ModuleGlobs(module, derive_fallback_lint_id) => {
@ -668,11 +657,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Ok(binding)
}
Err(ControlFlow::Continue(determinacy)) => Err(determinacy),
Err(ControlFlow::Break(determinacy)) => {
return Err(ControlFlow::Break(Determinacy::determined(
determinacy == Determinacy::Determined || force,
)));
}
Err(ControlFlow::Break(..)) => return binding,
}
}
Scope::MacroUsePrelude => match self.macro_use_prelude.get(&ident.name).cloned() {
@ -715,7 +700,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::Module(ns, prelude),
parent_scope,
None,
false,
ignore_decl,
ignore_import,
)
@ -951,7 +935,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::Module(ns, module),
parent_scope,
finalize,
finalize.is_some(),
ignore_decl,
ignore_import,
),
@ -960,7 +943,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::ModuleAndExternPrelude(ns, module),
parent_scope,
finalize,
finalize.is_some(),
ignore_decl,
ignore_import,
),
@ -973,7 +955,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::ExternPrelude,
parent_scope,
finalize,
finalize.is_some(),
ignore_decl,
ignore_import,
)
@ -996,7 +977,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::All(ns),
parent_scope,
finalize,
finalize.is_some(),
ignore_decl,
ignore_import,
)
@ -1180,7 +1160,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::Module(ns, module),
adjusted_parent_scope,
None,
false,
ignore_decl,
ignore_import,
);
@ -1881,7 +1860,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::All(ns),
parent_scope,
finalize,
finalize.is_some(),
ignore_decl,
ignore_import,
)
@ -1957,8 +1935,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
);
}
}
Err(Undetermined) => return PathResult::Indeterminate,
Err(Determined) => {
Err(Undetermined) if finalize.is_none() => return PathResult::Indeterminate,
Err(Determined | Undetermined) => {
if let Some(ModuleOrUniformRoot::Module(module)) = module
&& opt_ns.is_some()
&& !module.is_normal()

View file

@ -1498,7 +1498,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::All(ns),
&import.parent_scope,
None,
false,
decls[ns].get().decl(),
None,
) {

View file

@ -799,10 +799,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::Macro(kind),
parent_scope,
None,
force,
None,
None,
);
let binding = binding.map_err(|determinacy| {
Determinacy::determined(determinacy == Determinacy::Determined || force)
});
if let Err(Determinacy::Undetermined) = binding {
return Err(Determinacy::Undetermined);
}
@ -958,7 +960,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::Macro(kind),
&parent_scope,
Some(Finalize::new(ast::CRATE_NODE_ID, ident.span)),
true,
None,
None,
) {
@ -1013,7 +1014,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::Macro(MacroKind::Attr),
&parent_scope,
Some(Finalize::new(ast::CRATE_NODE_ID, ident.span)),
true,
None,
None,
);
@ -1117,7 +1117,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::Macro(MacroKind::Bang),
&ParentScope { macro_rules: no_macro_rules, ..*parent_scope },
None,
false,
None,
None,
);

View file

@ -1995,6 +1995,7 @@ symbols! {
rustc_no_implicit_autorefs,
rustc_no_implicit_bounds,
rustc_no_mir_inline,
rustc_non_const_trait_method,
rustc_nonnull_optimization_guaranteed,
rustc_nounwind,
rustc_objc_class,

View file

@ -279,7 +279,8 @@ pub trait FromIterator<A>: Sized {
)]
#[rustc_skip_during_method_dispatch(array, boxed_slice)]
#[stable(feature = "rust1", since = "1.0.0")]
pub trait IntoIterator {
#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
pub const trait IntoIterator {
/// The type of the elements being iterated over.
#[rustc_diagnostic_item = "IntoIteratorItem"]
#[stable(feature = "rust1", since = "1.0.0")]
@ -312,7 +313,8 @@ pub trait IntoIterator {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator> IntoIterator for I {
#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
impl<I: [const] Iterator> const IntoIterator for I {
type Item = I::Item;
type IntoIter = I;

View file

@ -37,7 +37,8 @@ fn _assert_is_dyn_compatible(_: &dyn Iterator<Item = ()>) {}
#[lang = "iterator"]
#[rustc_diagnostic_item = "Iterator"]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub trait Iterator {
#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
pub const trait Iterator {
/// The type of the elements being iterated over.
#[rustc_diagnostic_item = "IteratorItem"]
#[stable(feature = "rust1", since = "1.0.0")]
@ -107,6 +108,7 @@ pub trait Iterator {
/// ```
#[inline]
#[unstable(feature = "iter_next_chunk", issue = "98326")]
#[rustc_non_const_trait_method]
fn next_chunk<const N: usize>(
&mut self,
) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>>
@ -219,6 +221,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn count(self) -> usize
where
Self: Sized,
@ -251,6 +254,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn last(self) -> Option<Self::Item>
where
Self: Sized,
@ -298,6 +302,7 @@ pub trait Iterator {
/// ```
#[inline]
#[unstable(feature = "iter_advance_by", issue = "77404")]
#[rustc_non_const_trait_method]
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
/// Helper trait to specialize `advance_by` via `try_fold` for `Sized` iterators.
trait SpecAdvanceBy {
@ -375,6 +380,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.advance_by(n).ok()?;
self.next()
@ -425,6 +431,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "iterator_step_by", since = "1.28.0")]
#[rustc_non_const_trait_method]
fn step_by(self, step: usize) -> StepBy<Self>
where
Self: Sized,
@ -496,6 +503,7 @@ pub trait Iterator {
/// [`OsStr`]: ../../std/ffi/struct.OsStr.html
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter>
where
Self: Sized,
@ -614,6 +622,7 @@ pub trait Iterator {
/// [`zip`]: crate::iter::zip
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
where
Self: Sized,
@ -657,6 +666,7 @@ pub trait Iterator {
/// [`intersperse_with`]: Iterator::intersperse_with
#[inline]
#[unstable(feature = "iter_intersperse", issue = "79524")]
#[rustc_non_const_trait_method]
fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
where
Self: Sized,
@ -715,6 +725,7 @@ pub trait Iterator {
/// [`intersperse`]: Iterator::intersperse
#[inline]
#[unstable(feature = "iter_intersperse", issue = "79524")]
#[rustc_non_const_trait_method]
fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where
Self: Sized,
@ -774,6 +785,7 @@ pub trait Iterator {
#[rustc_diagnostic_item = "IteratorMap"]
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn map<B, F>(self, f: F) -> Map<Self, F>
where
Self: Sized,
@ -819,6 +831,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "iterator_for_each", since = "1.21.0")]
#[rustc_non_const_trait_method]
fn for_each<F>(self, f: F)
where
Self: Sized,
@ -894,6 +907,7 @@ pub trait Iterator {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "iter_filter"]
#[rustc_non_const_trait_method]
fn filter<P>(self, predicate: P) -> Filter<Self, P>
where
Self: Sized,
@ -939,6 +953,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where
Self: Sized,
@ -986,6 +1001,7 @@ pub trait Iterator {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "enumerate_method"]
#[rustc_non_const_trait_method]
fn enumerate(self) -> Enumerate<Self>
where
Self: Sized,
@ -1057,6 +1073,7 @@ pub trait Iterator {
/// [`next`]: Iterator::next
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn peekable(self) -> Peekable<Self>
where
Self: Sized,
@ -1122,6 +1139,7 @@ pub trait Iterator {
#[inline]
#[doc(alias = "drop_while")]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where
Self: Sized,
@ -1200,6 +1218,7 @@ pub 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<P>(self, predicate: P) -> TakeWhile<Self, P>
where
Self: Sized,
@ -1288,6 +1307,7 @@ pub trait Iterator {
/// [`fuse`]: Iterator::fuse
#[inline]
#[stable(feature = "iter_map_while", since = "1.57.0")]
#[rustc_non_const_trait_method]
fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where
Self: Sized,
@ -1317,6 +1337,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn skip(self, n: usize) -> Skip<Self>
where
Self: Sized,
@ -1389,6 +1410,7 @@ pub trait Iterator {
#[doc(alias = "limit")]
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn take(self, n: usize) -> Take<Self>
where
Self: Sized,
@ -1436,6 +1458,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where
Self: Sized,
@ -1474,6 +1497,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where
Self: Sized,
@ -1558,6 +1582,7 @@ pub 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<Self>
where
Self: Sized,
@ -1714,6 +1739,7 @@ pub trait Iterator {
/// ```
#[inline]
#[unstable(feature = "iter_map_windows", issue = "87155")]
#[rustc_non_const_trait_method]
fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where
Self: Sized,
@ -1776,6 +1802,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn fuse(self) -> Fuse<Self>
where
Self: Sized,
@ -1860,6 +1887,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn inspect<F>(self, f: F) -> Inspect<Self, F>
where
Self: Sized,
@ -2019,6 +2047,7 @@ pub trait Iterator {
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"]
#[rustc_diagnostic_item = "iterator_collect_fn"]
#[rustc_non_const_trait_method]
fn collect<B: FromIterator<Self::Item>>(self) -> B
where
Self: Sized,
@ -2106,6 +2135,7 @@ pub trait Iterator {
/// [`collect`]: Iterator::collect
#[inline]
#[unstable(feature = "iterator_try_collect", issue = "94047")]
#[rustc_non_const_trait_method]
fn try_collect<B>(&mut self) -> ChangeOutputType<Self::Item, B>
where
Self: Sized,
@ -2178,6 +2208,7 @@ pub trait Iterator {
/// ```
#[inline]
#[unstable(feature = "iter_collect_into", issue = "94780")]
#[rustc_non_const_trait_method]
fn collect_into<E: Extend<Self::Item>>(self, collection: &mut E) -> &mut E
where
Self: Sized,
@ -2210,6 +2241,7 @@ pub trait Iterator {
/// assert_eq!(odd, [1, 3]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn partition<B, F>(self, f: F) -> (B, B)
where
Self: Sized,
@ -2272,6 +2304,7 @@ pub trait Iterator {
/// assert!(a[i..].iter().all(|n| n % 2 == 1)); // odds
/// ```
#[unstable(feature = "iter_partition_in_place", issue = "62543")]
#[rustc_non_const_trait_method]
fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize
where
Self: Sized + DoubleEndedIterator<Item = &'a mut T>,
@ -2329,6 +2362,7 @@ pub trait Iterator {
/// assert!(!"IntoIterator".chars().is_partitioned(char::is_uppercase));
/// ```
#[unstable(feature = "iter_is_partitioned", issue = "62544")]
#[rustc_non_const_trait_method]
fn is_partitioned<P>(mut self, mut predicate: P) -> bool
where
Self: Sized,
@ -2423,6 +2457,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "iterator_try_fold", since = "1.27.0")]
#[rustc_non_const_trait_method]
fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
where
Self: Sized,
@ -2481,6 +2516,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "iterator_try_fold", since = "1.27.0")]
#[rustc_non_const_trait_method]
fn try_for_each<F, R>(&mut self, f: F) -> R
where
Self: Sized,
@ -2600,6 +2636,7 @@ pub trait Iterator {
#[doc(alias = "inject", alias = "foldl")]
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn fold<B, F>(mut self, init: B, mut f: F) -> B
where
Self: Sized,
@ -2637,6 +2674,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "iterator_fold_self", since = "1.51.0")]
#[rustc_non_const_trait_method]
fn reduce<F>(mut self, f: F) -> Option<Self::Item>
where
Self: Sized,
@ -2708,6 +2746,7 @@ pub trait Iterator {
/// ```
#[inline]
#[unstable(feature = "iterator_try_reduce", issue = "87053")]
#[rustc_non_const_trait_method]
fn try_reduce<R>(
&mut self,
f: impl FnMut(Self::Item, Self::Item) -> R,
@ -2766,6 +2805,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn all<F>(&mut self, f: F) -> bool
where
Self: Sized,
@ -2819,6 +2859,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn any<F>(&mut self, f: F) -> bool
where
Self: Sized,
@ -2892,6 +2933,7 @@ pub trait Iterator {
/// Note that `iter.find(f)` is equivalent to `iter.filter(f).next()`.
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where
Self: Sized,
@ -2923,6 +2965,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "iterator_find_map", since = "1.30.0")]
#[rustc_non_const_trait_method]
fn find_map<B, F>(&mut self, f: F) -> Option<B>
where
Self: Sized,
@ -2981,6 +3024,7 @@ pub trait Iterator {
/// ```
#[inline]
#[unstable(feature = "try_find", issue = "63178")]
#[rustc_non_const_trait_method]
fn try_find<R>(
&mut self,
f: impl FnMut(&Self::Item) -> R,
@ -3064,6 +3108,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn position<P>(&mut self, predicate: P) -> Option<usize>
where
Self: Sized,
@ -3129,6 +3174,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn rposition<P>(&mut self, predicate: P) -> Option<usize>
where
P: FnMut(Self::Item) -> bool,
@ -3178,6 +3224,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn max(self) -> Option<Self::Item>
where
Self: Sized,
@ -3214,6 +3261,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn min(self) -> Option<Self::Item>
where
Self: Sized,
@ -3236,6 +3284,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
#[rustc_non_const_trait_method]
fn max_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
where
Self: Sized,
@ -3269,6 +3318,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "iter_max_by", since = "1.15.0")]
#[rustc_non_const_trait_method]
fn max_by<F>(self, compare: F) -> Option<Self::Item>
where
Self: Sized,
@ -3296,6 +3346,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
#[rustc_non_const_trait_method]
fn min_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
where
Self: Sized,
@ -3329,6 +3380,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "iter_min_by", since = "1.15.0")]
#[rustc_non_const_trait_method]
fn min_by<F>(self, compare: F) -> Option<Self::Item>
where
Self: Sized,
@ -3366,6 +3418,7 @@ pub trait Iterator {
#[inline]
#[doc(alias = "reverse")]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn rev(self) -> Rev<Self>
where
Self: Sized + DoubleEndedIterator,
@ -3402,6 +3455,7 @@ pub trait Iterator {
/// assert_eq!(z, [3, 6]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where
FromA: Default + Extend<A>,
@ -3433,6 +3487,7 @@ pub 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<Self>
where
T: Copy + 'a,
@ -3481,6 +3536,7 @@ pub 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<Self>
where
T: Clone + 'a,
@ -3512,6 +3568,7 @@ pub trait Iterator {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
#[rustc_non_const_trait_method]
fn cycle(self) -> Cycle<Self>
where
Self: Sized + Clone,
@ -3555,6 +3612,7 @@ pub trait Iterator {
/// ```
#[track_caller]
#[unstable(feature = "iter_array_chunks", issue = "100450")]
#[rustc_non_const_trait_method]
fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where
Self: Sized,
@ -3591,6 +3649,7 @@ pub trait Iterator {
/// assert_eq!(sum, -0.0_f32);
/// ```
#[stable(feature = "iter_arith", since = "1.11.0")]
#[rustc_non_const_trait_method]
fn sum<S>(self) -> S
where
Self: Sized,
@ -3623,6 +3682,7 @@ pub trait Iterator {
/// assert_eq!(factorial(5), 120);
/// ```
#[stable(feature = "iter_arith", since = "1.11.0")]
#[rustc_non_const_trait_method]
fn product<P>(self) -> P
where
Self: Sized,
@ -3644,6 +3704,7 @@ pub trait Iterator {
/// assert_eq!([1, 2].iter().cmp([1].iter()), Ordering::Greater);
/// ```
#[stable(feature = "iter_order", since = "1.5.0")]
#[rustc_non_const_trait_method]
fn cmp<I>(self, other: I) -> Ordering
where
I: IntoIterator<Item = Self::Item>,
@ -3671,6 +3732,7 @@ pub trait Iterator {
/// assert_eq!(xs.into_iter().cmp_by(ys, |x, y| (2 * x).cmp(&y)), Ordering::Greater);
/// ```
#[unstable(feature = "iter_order_by", issue = "64295")]
#[rustc_non_const_trait_method]
fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where
Self: Sized,
@ -3727,6 +3789,7 @@ pub trait Iterator {
/// ```
///
#[stable(feature = "iter_order", since = "1.5.0")]
#[rustc_non_const_trait_method]
fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where
I: IntoIterator,
@ -3763,6 +3826,7 @@ pub trait Iterator {
/// );
/// ```
#[unstable(feature = "iter_order_by", issue = "64295")]
#[rustc_non_const_trait_method]
fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where
Self: Sized,
@ -3796,6 +3860,7 @@ pub trait Iterator {
/// assert_eq!([1].iter().eq([1, 2].iter()), false);
/// ```
#[stable(feature = "iter_order", since = "1.5.0")]
#[rustc_non_const_trait_method]
fn eq<I>(self, other: I) -> bool
where
I: IntoIterator,
@ -3819,6 +3884,7 @@ pub trait Iterator {
/// assert!(xs.iter().eq_by(ys, |x, y| x * x == y));
/// ```
#[unstable(feature = "iter_order_by", issue = "64295")]
#[rustc_non_const_trait_method]
fn eq_by<I, F>(self, other: I, eq: F) -> bool
where
Self: Sized,
@ -3848,6 +3914,7 @@ pub trait Iterator {
/// assert_eq!([1].iter().ne([1, 2].iter()), true);
/// ```
#[stable(feature = "iter_order", since = "1.5.0")]
#[rustc_non_const_trait_method]
fn ne<I>(self, other: I) -> bool
where
I: IntoIterator,
@ -3869,6 +3936,7 @@ pub trait Iterator {
/// assert_eq!([1, 2].iter().lt([1, 2].iter()), false);
/// ```
#[stable(feature = "iter_order", since = "1.5.0")]
#[rustc_non_const_trait_method]
fn lt<I>(self, other: I) -> bool
where
I: IntoIterator,
@ -3890,6 +3958,7 @@ pub trait Iterator {
/// assert_eq!([1, 2].iter().le([1, 2].iter()), true);
/// ```
#[stable(feature = "iter_order", since = "1.5.0")]
#[rustc_non_const_trait_method]
fn le<I>(self, other: I) -> bool
where
I: IntoIterator,
@ -3911,6 +3980,7 @@ pub trait Iterator {
/// assert_eq!([1, 2].iter().gt([1, 2].iter()), false);
/// ```
#[stable(feature = "iter_order", since = "1.5.0")]
#[rustc_non_const_trait_method]
fn gt<I>(self, other: I) -> bool
where
I: IntoIterator,
@ -3932,6 +4002,7 @@ pub trait Iterator {
/// assert_eq!([1, 2].iter().ge([1, 2].iter()), true);
/// ```
#[stable(feature = "iter_order", since = "1.5.0")]
#[rustc_non_const_trait_method]
fn ge<I>(self, other: I) -> bool
where
I: IntoIterator,
@ -3961,6 +4032,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "is_sorted", since = "1.82.0")]
#[rustc_non_const_trait_method]
fn is_sorted(self) -> bool
where
Self: Sized,
@ -3987,6 +4059,7 @@ pub trait Iterator {
/// assert!(std::iter::empty::<i32>().is_sorted_by(|a, b| true));
/// ```
#[stable(feature = "is_sorted", since = "1.82.0")]
#[rustc_non_const_trait_method]
fn is_sorted_by<F>(mut self, compare: F) -> bool
where
Self: Sized,
@ -4031,6 +4104,7 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "is_sorted", since = "1.82.0")]
#[rustc_non_const_trait_method]
fn is_sorted_by_key<F, K>(self, f: F) -> bool
where
Self: Sized,
@ -4046,6 +4120,7 @@ pub trait Iterator {
#[inline]
#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
#[rustc_non_const_trait_method]
unsafe fn __iterator_get_unchecked(&mut self, _idx: usize) -> Self::Item
where
Self: TrustedRandomAccessNoCoerce,

View file

@ -2257,7 +2257,8 @@ impl<T> const Default for Option<T> {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> IntoIterator for Option<T> {
#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
impl<T> const IntoIterator for Option<T> {
type Item = T;
type IntoIter = IntoIter<T>;
@ -2429,7 +2430,8 @@ struct Item<A> {
opt: Option<A>,
}
impl<A> Iterator for Item<A> {
#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
impl<A> const Iterator for Item<A> {
type Item = A;
#[inline]
@ -2439,7 +2441,7 @@ impl<A> Iterator for Item<A> {
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
let len = self.opt.len();
(len, Some(len))
}
}
@ -2563,7 +2565,8 @@ pub struct IntoIter<A> {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A> Iterator for IntoIter<A> {
#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
impl<A> const Iterator for IntoIter<A> {
type Item = A;
#[inline]

View file

@ -99,3 +99,18 @@ pub fn extend_for_unit() {
}
assert_eq!(x, 5);
}
#[test]
pub fn test_const_iter() {
const X: bool = {
let it = Some(42);
let mut run = false;
#[expect(for_loops_over_fallibles)]
for x in it {
assert!(x == 42);
run = true;
}
run
};
assert_eq!(true, X);
}

View file

@ -27,6 +27,7 @@
#![feature(const_drop_in_place)]
#![feature(const_eval_select)]
#![feature(const_index)]
#![feature(const_iter)]
#![feature(const_ops)]
#![feature(const_option_ops)]
#![feature(const_ref_cell)]

View file

@ -199,7 +199,7 @@
- [Inference details](./opaque-types-impl-trait-inference.md)
- [Return Position Impl Trait In Trait](./return-position-impl-trait-in-trait.md)
- [Region inference restrictions](./borrow-check/opaque-types-region-inference-restrictions.md)
- [Const condition checking](./effects.md)
- [Const traits and const condition checking](./effects.md)
- [Pattern and exhaustiveness checking](./pat-exhaustive-checking.md)
- [Unsafety checking](./unsafety-checking.md)
- [MIR dataflow](./mir/dataflow.md)

View file

@ -1,4 +1,4 @@
# Effects and const condition checking
# Effects, const traits, and const condition checking
## The `HostEffect` predicate
@ -154,3 +154,18 @@ be dropped at compile time.
[old solver]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_trait_selection/traits/effects.rs.html
[new trait solver]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_next_trait_solver/solve/effect_goals.rs.html
## More on const traits
To be expanded later.
### The `#[rustc_non_const_trait_method]` attribute
This is intended for internal (standard library) usage only. With this attribute
applied to a trait method, the compiler will not check the default body of this
method for ability to run in compile time. Users of the trait will also not be
allowed to use this trait method in const contexts. This attribute is primarily
used for constifying large traits such as `Iterator` without having to make all
its methods `const` at the same time.
This attribute should not be present while stabilizing the trait as `const`.

View file

@ -5,5 +5,4 @@ macro_rules! sample { () => {} }
#[sample] //~ ERROR cannot find attribute `sample` in this scope
#[derive(sample)] //~ ERROR cannot find derive macro `sample` in this scope
//~| ERROR cannot find derive macro `sample` in this scope
//~| ERROR cannot find derive macro `sample` in this scope
pub struct S {}

View file

@ -1,12 +1,3 @@
error: cannot find derive macro `sample` in this scope
--> $DIR/macro-rules-as-derive-or-attr-issue-132928.rs:6:10
|
LL | macro_rules! sample { () => {} }
| ------ `sample` exists, but has no `derive` rules
...
LL | #[derive(sample)]
| ^^^^^^
error: cannot find attribute `sample` in this scope
--> $DIR/macro-rules-as-derive-or-attr-issue-132928.rs:5:3
|
@ -24,8 +15,6 @@ LL | macro_rules! sample { () => {} }
...
LL | #[derive(sample)]
| ^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: cannot find derive macro `sample` in this scope
--> $DIR/macro-rules-as-derive-or-attr-issue-132928.rs:6:10
@ -38,5 +27,5 @@ LL | #[derive(sample)]
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 4 previous errors
error: aborting due to 3 previous errors

View file

@ -0,0 +1,7 @@
trait A {
#[rustc_non_const_trait_method]
//~^ ERROR: use of an internal attribute
fn a();
}
fn main() {}

View file

@ -0,0 +1,13 @@
error[E0658]: use of an internal attribute
--> $DIR/attr-gate.rs:2:5
|
LL | #[rustc_non_const_trait_method]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
= note: the `#[rustc_non_const_trait_method]` attribute is an internal implementation detail that will never be stable
= note: `#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods as non-const to allow large traits an easier transition to const
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0658`.

View file

@ -0,0 +1,39 @@
#![feature(const_trait_impl, rustc_attrs)]
const trait A {
fn a();
#[rustc_non_const_trait_method]
fn b() { println!("hi"); }
}
impl const A for () {
fn a() {}
}
impl const A for u8 {
fn a() {}
fn b() { println!("hello"); }
//~^ ERROR: cannot call non-const function
}
impl const A for i8 {
fn a() {}
fn b() {}
}
const fn foo<T: [const] A>() {
T::a();
T::b();
//~^ ERROR: cannot call non-const associated function
<()>::a();
<()>::b();
//~^ ERROR: cannot call non-const associated function
u8::a();
u8::b();
//~^ ERROR: cannot call non-const associated function
i8::a();
i8::b();
//~^ ERROR: cannot call non-const associated function
}
fn main() {}

View file

@ -0,0 +1,45 @@
error[E0015]: cannot call non-const function `std::io::_print` in constant functions
--> $DIR/no-const-callers.rs:15:14
|
LL | fn b() { println!("hello"); }
| ^^^^^^^^^^^^^^^^^
|
note: function `_print` is not const
--> $SRC_DIR/std/src/io/stdio.rs:LL:COL
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error[E0015]: cannot call non-const associated function `<T as A>::b` in constant functions
--> $DIR/no-const-callers.rs:26:5
|
LL | T::b();
| ^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error[E0015]: cannot call non-const associated function `<() as A>::b` in constant functions
--> $DIR/no-const-callers.rs:29:5
|
LL | <()>::b();
| ^^^^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error[E0015]: cannot call non-const associated function `<u8 as A>::b` in constant functions
--> $DIR/no-const-callers.rs:32:5
|
LL | u8::b();
| ^^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error[E0015]: cannot call non-const associated function `<i8 as A>::b` in constant functions
--> $DIR/no-const-callers.rs:35:5
|
LL | i8::b();
| ^^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0015`.

View file

@ -684,13 +684,6 @@ error[E0015]: cannot call non-const method `<std::ops::Range<i32> as Iterator>::
LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
| ^^^^^^^^^^^^^^^^^^^^^^
|
note: method `filter` is not const because trait `Iterator` is not const
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
= note: this trait is not const
::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
= note: this method is not const
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
error[E0015]: cannot call non-const method `<Filter<std::ops::Range<i32>, {closure@$DIR/typeck_type_placeholder_item.rs:240:29: 240:32}> as Iterator>::map::<i32, {closure@$DIR/typeck_type_placeholder_item.rs:240:49: 240:52}>` in constants
@ -699,13 +692,6 @@ error[E0015]: cannot call non-const method `<Filter<std::ops::Range<i32>, {closu
LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
| ^^^^^^^^^^^^^^
|
note: method `map` is not const because trait `Iterator` is not const
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
= note: this trait is not const
::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
= note: this method is not const
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
error: aborting due to 83 previous errors