You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Default implementation on std::iter::Fuse should not requires Default on the inner iterator #140961
let items = match std::fs::read_dir(&path){Ok(v) => v.fuse(),Err(e)if e.kind() == ErrorKind::NotFound => Default::default(),// This line won't compile.Err(e) => returnErr(e),};
The problem is that Fuse::<I>::default() calls I::default(), which is free to yield some elements. Maybe we should add a Fuse::<I>::exhausted() which is guaranteed to yield no elements?
Oh no… that’s what the documentation of impl Default for Fuse says, but the current implementation actually constructs Fuse { iter: Default::default() } which is Fuse { iter: None } because the field is Option<I>.
For a workaround for the original code snippet, assuming you want an empty iterator in the ErrorKind::NotFound case, there are a few things you could do.
If you don't mind an additional heap allocation and dynamic dispatch, you could use Box<dyn Iterator>:
Or, if you are using Rust 1.79.0 or later and depending on how you use items, you could use dynamic dispatch with the new temporary value lifetime extension semantics in match:
let items:&mutdynIterator<Item = _> = match std::fs::read_dir(&path){Ok(v) => &mut{v},// the braces are required, to move `v` out of the variable into a temporary whose lifetime can be extendedErr(e)if e.kind() == ErrorKind::NotFound => &mut std::iter::empty(),Err(e) => returnErr(e),};
Thanks for the idea. I don't mind using a workaround but I think it is better to be able to construct Fuse directly is better (e.g. provide additional method like @ShE3py said). Also I think changing the current behavior of Fuse::default is a breaking change since people might already depend on its current behavior.
The issue title has been resolved, since #140985 merged so <Fuse<I> as Default>::default now calls I::default (as it was documented to), so it does require I: Default.
The issue could be renamed to reflect the feature request for an exhausted() -> Fuse function, but generally library feature requests go through the API Change Proposal process. If you have a use-case for producing a Fuse that is already exhausted, you could maybe submit an ACP for a pub const fn exhausted() -> Self on Fuse.
Activity
ShE3py commentedon May 13, 2025
The problem is that
Fuse::<I>::default()callsI::default(), which is free to yield some elements. Maybe we should add aFuse::<I>::exhausted()which is guaranteed to yield no elements?@rustbot label +T-libs-api +C-feature-request +A-iterators -needs-triage
hanna-kruppe commentedon May 13, 2025
Oh no… that’s what the documentation of
impl Default for Fusesays, but the current implementation actually constructsFuse { iter: Default::default() }which isFuse { iter: None }because the field isOption<I>.zachs18 commentedon May 14, 2025
For a workaround for the original code snippet, assuming you want an empty iterator in the
ErrorKind::NotFoundcase, there are a few things you could do.If you don't mind an additional heap allocation and dynamic dispatch, you could use
Box<dyn Iterator>:Or you could use
Option::into_iterandIterator::flatten, e.g.Or you could use
either::Either:Or, if you are using Rust 1.79.0 or later and depending on how you use
items, you could use dynamic dispatch with the new temporary value lifetime extension semantics inmatch:ultimaweapon commentedon May 14, 2025
Thanks for the idea. I don't mind using a workaround but I think it is better to be able to construct
Fusedirectly is better (e.g. provide additional method like @ShE3py said). Also I think changing the current behavior ofFuse::defaultis a breaking change since people might already depend on its current behavior.Auto merge of rust-lang#140985 - zachs18:fuse-default-some, r=<try>
Rollup merge of rust-lang#140985 - zachs18:fuse-default-some, r=tgross35
Unrolled build for #140985
Rollup merge of rust-lang#140985 - zachs18:fuse-default-some, r=tgross35
zachs18 commentedon Jul 10, 2025
The issue title has been resolved, since #140985 merged so
<Fuse<I> as Default>::defaultnow callsI::default(as it was documented to), so it does requireI: Default.The issue could be renamed to reflect the feature request for an
exhausted() -> Fusefunction, but generally library feature requests go through the API Change Proposal process. If you have a use-case for producing aFusethat is already exhausted, you could maybe submit an ACP for apub const fn exhausted() -> SelfonFuse.ultimaweapon commentedon Jul 11, 2025
Thanks for the information.