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
29 changed files with 286 additions and 85 deletions
@@ -388,3 +388,15 @@ fn extend(
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;
}
+4 -3
View File
@@ -79,9 +79,9 @@
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 @@ mod late {
Single<WithoutArgs<RustcMainParser>>,
Single<WithoutArgs<RustcNeverReturnsNullPointerParser>>,
Single<WithoutArgs<RustcNoImplicitAutorefsParser>>,
Single<WithoutArgs<RustcNonConstTraitMethodParser>>,
Single<WithoutArgs<RustcNounwindParser>>,
Single<WithoutArgs<RustcOffloadKernelParser>>,
Single<WithoutArgs<RustcPassIndirectlyInNonRusticAbisParser>>,
@@ -774,16 +774,16 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
// 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,
@@ -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),
@@ -1329,6 +1329,12 @@ pub struct 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,
@@ -1096,6 +1096,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_no_implicit_autorefs]`
RustcNoImplicitAutorefs,
/// Represents `#[rustc_non_const_trait_method]`.
RustcNonConstTraitMethod,
/// Represents `#[rustc_nounwind]`
RustcNounwind,
@@ -124,6 +124,7 @@ pub fn encode_cross_crate(&self) -> EncodeCrossCrate {
RustcMustImplementOneOf { .. } => No,
RustcNeverReturnsNullPointer => Yes,
RustcNoImplicitAutorefs => Yes,
RustcNonConstTraitMethod => No, // should be reported via other queries like `constness`
RustcNounwind => No,
RustcObjcClass { .. } => No,
RustcObjcSelector { .. } => No,
@@ -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.
+10 -2
View File
@@ -2086,8 +2086,16 @@ pub fn is_conditionally_const(self, def_id: impl Into<DefId>) -> bool {
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:?}"),
}
+1 -1
View File
@@ -310,6 +310,7 @@ fn check_attributes(
| AttributeKind::RustcMain
| AttributeKind::RustcNeverReturnsNullPointer
| AttributeKind::RustcNoImplicitAutorefs
| AttributeKind::RustcNonConstTraitMethod
| AttributeKind::RustcNounwind
| AttributeKind::RustcObjcClass { .. }
| AttributeKind::RustcObjcSelector { .. }
@@ -335,7 +336,6 @@ fn check_attributes(
| AttributeKind::Used { .. }
| AttributeKind::WindowsSubsystem(..)
// tidy-alphabetical-end
) => { /* do nothing */ }
Attribute::Unparsed(attr_item) => {
style = Some(attr_item.style);
@@ -1709,7 +1709,6 @@ pub(crate) fn unresolved_macro_suggestions(
ScopeSet::All(ns),
parent_scope,
None,
false,
None,
None,
) else {
@@ -2546,7 +2545,6 @@ pub(crate) fn report_path_resolution_error(
ScopeSet::All(ns_to_try),
parent_scope,
None,
false,
ignore_decl,
ignore_import,
)
@@ -2650,7 +2648,6 @@ pub(crate) fn report_path_resolution_error(
ScopeSet::All(ValueNS),
parent_scope,
None,
false,
ignore_decl,
ignore_import,
) {
+6 -28
View File
@@ -350,7 +350,6 @@ pub(crate) fn resolve_ident_in_lexical_scope(
ScopeSet::Module(ns, module),
parent_scope,
finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
finalize.is_some(),
ignore_decl,
None,
)
@@ -368,7 +367,6 @@ pub(crate) fn resolve_ident_in_lexical_scope(
ScopeSet::All(ns),
parent_scope,
finalize,
finalize.is_some(),
ignore_decl,
None,
)
@@ -396,12 +394,9 @@ pub(crate) fn resolve_ident_in_scope_set<'r>(
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 @@ pub(crate) fn resolve_ident_in_scope_set<'r>(
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 @@ pub(crate) fn resolve_ident_in_scope_set<'r>(
// 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 @@ fn resolve_ident_in_scope<'r>(
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 @@ fn resolve_ident_in_scope<'r>(
match self.reborrow().resolve_derive_macro_path(
derive,
parent_scope,
force,
false,
ignore_import,
) {
Ok((Some(ext), _)) => {
@@ -617,11 +610,7 @@ fn resolve_ident_in_scope<'r>(
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 @@ fn resolve_ident_in_scope<'r>(
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 @@ fn resolve_ident_in_scope<'r>(
ScopeSet::Module(ns, prelude),
parent_scope,
None,
false,
ignore_decl,
ignore_import,
)
@@ -951,7 +935,6 @@ fn resolve_ident_in_virt_module_unadjusted<'r>(
ScopeSet::Module(ns, module),
parent_scope,
finalize,
finalize.is_some(),
ignore_decl,
ignore_import,
),
@@ -960,7 +943,6 @@ fn resolve_ident_in_virt_module_unadjusted<'r>(
ScopeSet::ModuleAndExternPrelude(ns, module),
parent_scope,
finalize,
finalize.is_some(),
ignore_decl,
ignore_import,
),
@@ -973,7 +955,6 @@ fn resolve_ident_in_virt_module_unadjusted<'r>(
ScopeSet::ExternPrelude,
parent_scope,
finalize,
finalize.is_some(),
ignore_decl,
ignore_import,
)
@@ -996,7 +977,6 @@ fn resolve_ident_in_virt_module_unadjusted<'r>(
ScopeSet::All(ns),
parent_scope,
finalize,
finalize.is_some(),
ignore_decl,
ignore_import,
)
@@ -1180,7 +1160,6 @@ fn resolve_ident_in_module_globs_unadjusted<'r>(
ScopeSet::Module(ns, module),
adjusted_parent_scope,
None,
false,
ignore_decl,
ignore_import,
);
@@ -1881,7 +1860,6 @@ fn record_segment_res<'r, 'ra, 'tcx>(
ScopeSet::All(ns),
parent_scope,
finalize,
finalize.is_some(),
ignore_decl,
ignore_import,
)
@@ -1957,8 +1935,8 @@ fn record_segment_res<'r, '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()
-1
View File
@@ -1498,7 +1498,6 @@ pub(crate) fn check_for_redundant_imports(&mut self, import: Import<'ra>) -> boo
ScopeSet::All(ns),
&import.parent_scope,
None,
false,
decls[ns].get().decl(),
None,
) {
+3 -4
View File
@@ -799,10 +799,12 @@ fn resolve_macro_or_delegation_path<'r>(
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 @@ pub(crate) fn finalize_macro_resolutions(&mut self, krate: &Crate) {
ScopeSet::Macro(kind),
&parent_scope,
Some(Finalize::new(ast::CRATE_NODE_ID, ident.span)),
true,
None,
None,
) {
@@ -1013,7 +1014,6 @@ pub(crate) fn finalize_macro_resolutions(&mut self, krate: &Crate) {
ScopeSet::Macro(MacroKind::Attr),
&parent_scope,
Some(Finalize::new(ast::CRATE_NODE_ID, ident.span)),
true,
None,
None,
);
@@ -1117,7 +1117,6 @@ fn report_out_of_scope_macro_calls<'r>(
ScopeSet::Macro(MacroKind::Bang),
&ParentScope { macro_rules: no_macro_rules, ..*parent_scope },
None,
false,
None,
None,
);
+1
View File
@@ -1995,6 +1995,7 @@
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,
+4 -2
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;
+76 -1
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 @@ fn size_hint(&self) -> (usize, Option<usize>) {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_non_const_trait_method]
fn count(self) -> usize
where
Self: Sized,
@@ -251,6 +254,7 @@ fn count(self) -> usize
/// ```
#[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 @@ fn some<T>(_: Option<T>, x: T) -> Option<T> {
/// ```
#[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 @@ fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
/// ```
#[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 @@ fn nth(&mut self, n: usize) -> Option<Self::Item> {
/// ```
#[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 @@ fn step_by(self, step: usize) -> StepBy<Self>
/// [`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 @@ fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter>
/// [`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 @@ fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
/// [`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 @@ fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
/// [`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 @@ fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
#[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 @@ fn map<B, F>(self, f: F) -> Map<Self, F>
/// ```
#[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 @@ fn call<T>(mut f: impl FnMut(T)) -> impl FnMut((), T) {
#[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 @@ fn filter<P>(self, predicate: P) -> Filter<Self, P>
/// ```
#[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 @@ fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
#[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 @@ fn enumerate(self) -> Enumerate<Self>
/// [`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 @@ fn peekable(self) -> Peekable<Self>
#[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 @@ fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
/// 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 @@ fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
/// [`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 @@ fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
/// ```
#[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 @@ fn skip(self, n: usize) -> Skip<Self>
#[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 @@ fn take(self, n: usize) -> Take<Self>
/// ```
#[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 @@ fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
/// ```
#[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 @@ fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
/// [`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 @@ fn flatten(self) -> Flatten<Self>
/// ```
#[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 @@ fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
/// ```
#[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 @@ fn fuse(self) -> Fuse<Self>
/// ```
#[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 @@ fn by_ref(&mut self) -> &mut Self
#[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 @@ fn collect<B: FromIterator<Self::Item>>(self) -> B
/// [`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 @@ fn try_collect<B>(&mut self) -> ChangeOutputType<Self::Item, B>
/// ```
#[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 @@ fn collect_into<E: Extend<Self::Item>>(self, collection: &mut E) -> &mut E
/// 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 @@ fn extend<'a, T, B: Extend<T>>(
/// 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 @@ fn is_true<T>(predicate: &mut impl FnMut(&T) -> bool) -> impl FnMut(&&mut T) ->
/// 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 @@ fn is_partitioned<P>(mut self, mut predicate: P) -> bool
/// ```
#[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 @@ fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
/// ```
#[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 @@ fn call<T, R>(mut f: impl FnMut(T) -> R) -> impl FnMut((), T) -> R {
#[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 @@ fn fold<B, F>(mut self, init: B, mut f: F) -> B
/// ```
#[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 @@ fn reduce<F>(mut self, f: F) -> Option<Self::Item>
/// ```
#[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 @@ fn try_reduce<R>(
/// ```
#[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 @@ fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()
/// ```
#[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 @@ fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()
/// 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 @@ fn check<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> Contr
/// ```
#[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 @@ fn check<T, B>(mut f: impl FnMut(T) -> Option<B>) -> impl FnMut((), T) -> Contro
/// ```
#[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 @@ fn check<I, V, R>(
/// ```
#[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 @@ fn check<'a, T>(
/// ```
#[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 @@ fn check<T>(
/// ```
#[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 @@ fn max(self) -> Option<Self::Item>
/// ```
#[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 @@ fn min(self) -> Option<Self::Item>
/// ```
#[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 @@ fn compare<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> Ordering {
/// ```
#[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 @@ fn fold<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(T, T) -> T
/// ```
#[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 @@ fn compare<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> Ordering {
/// ```
#[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 @@ fn fold<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(T, T) -> T
#[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 @@ fn rev(self) -> Rev<Self>
/// 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 @@ fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
/// ```
#[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 @@ fn copied<'a, T>(self) -> Copied<Self>
/// ```
#[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 @@ fn cloned<'a, T>(self) -> Cloned<Self>
/// ```
#[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 @@ fn cycle(self) -> Cycle<Self>
/// ```
#[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 @@ fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
/// 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 @@ fn sum<S>(self) -> S
/// 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 @@ fn product<P>(self) -> P
/// 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 @@ fn cmp<I>(self, other: I) -> Ordering
/// 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 @@ fn compare<X, Y, F>(mut cmp: F) -> impl FnMut(X, Y) -> ControlFlow<Ordering>
/// ```
///
#[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 @@ fn partial_cmp<I>(self, other: I) -> Option<Ordering>
/// );
/// ```
#[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 @@ fn compare<X, Y, F>(mut partial_cmp: F) -> impl FnMut(X, Y) -> ControlFlow<Optio
/// 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 @@ fn eq<I>(self, other: I) -> bool
/// 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 @@ fn compare<X, Y, F>(mut eq: F) -> impl FnMut(X, Y) -> ControlFlow<()>
/// 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 @@ fn ne<I>(self, other: I) -> bool
/// 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 @@ fn lt<I>(self, other: I) -> bool
/// 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 @@ fn le<I>(self, other: I) -> bool
/// 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 @@ fn gt<I>(self, other: I) -> bool
/// 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 @@ fn ge<I>(self, other: I) -> bool
/// ```
#[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 @@ fn is_sorted(self) -> bool
/// 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 @@ fn check<'a, T>(
/// ```
#[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 @@ fn is_sorted_by_key<F, K>(self, f: F) -> bool
#[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,
+7 -4
View File
@@ -2257,7 +2257,8 @@ fn default() -> 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 @@ fn next(&mut self) -> Option<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]
+15
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);
}
+1
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)]
+1 -1
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)
+16 -1
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`.
@@ -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 {}
@@ -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
@@ -0,0 +1,7 @@
trait A {
#[rustc_non_const_trait_method]
//~^ ERROR: use of an internal attribute
fn a();
}
fn main() {}
@@ -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`.
@@ -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() {}
@@ -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`.
@@ -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