My function returns impl Iterator. From one branch, I want to return std::iter::Once and from another branch I want to return std::iter::Repeat: use std::iter; fn trues(is_infinite: bool) -> impl Iterator<Item = bool> { if is_infinite { iter::repeat(true) } else { iter::once(true) } } let trues: impl Iterator<Item = bool> = trues(true); for tru in trues {} This feels like it should work - but of course what actually happens is impl Iterator hides the underlying type. There still must be just ...