1
Fork 0

fix most compiler/ doctests

This commit is contained in:
Elliot Roberts 2022-04-15 15:04:34 -07:00
parent bf611439e3
commit 7907385999
116 changed files with 666 additions and 609 deletions

View file

@ -742,7 +742,7 @@ impl<'hir> Map<'hir> {
/// }
/// ```
///
/// ```
/// ```compile_fail,E0308
/// fn foo(x: usize) -> bool {
/// loop {
/// true // If `get_return_block` gets passed the `id` corresponding

View file

@ -10,7 +10,7 @@ use rustc_span::Span;
/// Requires that `region` must be equal to one of the regions in `choice_regions`.
/// We often denote this using the syntax:
///
/// ```
/// ```text
/// R0 member of [O1..On]
/// ```
#[derive(Debug, Clone, HashStable, TypeFoldable, Lift)]

View file

@ -770,11 +770,11 @@ impl InitMask {
///
/// Note that all examples below are written with 8 (instead of 64) bit blocks for simplicity,
/// and with the least significant bit (and lowest block) first:
///
/// 00000000|00000000
/// ^ ^ ^ ^
/// index: 0 7 8 15
///
/// ```text
/// 00000000|00000000
/// ^ ^ ^ ^
/// index: 0 7 8 15
/// ```
/// Also, if not stated, assume that `is_init = true`, that is, we are searching for the first 1 bit.
fn find_bit_fast(
init_mask: &InitMask,

View file

@ -737,14 +737,14 @@ pub enum BorrowKind {
/// This is used when lowering matches: when matching on a place we want to
/// ensure that place have the same value from the start of the match until
/// an arm is selected. This prevents this code from compiling:
///
/// let mut x = &Some(0);
/// match *x {
/// None => (),
/// Some(_) if { x = &None; false } => (),
/// Some(_) => (),
/// }
///
/// ```compile_fail,E0510
/// let mut x = &Some(0);
/// match *x {
/// None => (),
/// Some(_) if { x = &None; false } => (),
/// Some(_) => (),
/// }
/// ```
/// This can't be a shared borrow because mutably borrowing (*x as Some).0
/// should not prevent `if let None = x { ... }`, for example, because the
/// mutating `(*x as Some).0` can't affect the discriminant of `x`.
@ -755,27 +755,30 @@ pub enum BorrowKind {
/// cannot currently be expressed by the user and is used only in
/// implicit closure bindings. It is needed when the closure is
/// borrowing or mutating a mutable referent, e.g.:
///
/// let x: &mut isize = ...;
/// let y = || *x += 5;
///
/// ```
/// let mut z = 3;
/// let x: &mut isize = &mut z;
/// let y = || *x += 5;
/// ```
/// If we were to try to translate this closure into a more explicit
/// form, we'd encounter an error with the code as written:
///
/// struct Env { x: & &mut isize }
/// let x: &mut isize = ...;
/// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
///
/// ```compile_fail,E0594
/// struct Env<'a> { x: &'a &'a mut isize }
/// let mut z = 3;
/// let x: &mut isize = &mut z;
/// let y = (&mut Env { x: &x }, fn_ptr); // Closure is pair of env and fn
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
/// ```
/// This is then illegal because you cannot mutate an `&mut` found
/// in an aliasable location. To solve, you'd have to translate with
/// an `&mut` borrow:
///
/// struct Env { x: &mut &mut isize }
/// let x: &mut isize = ...;
/// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
///
/// ```compile_fail,E0596
/// struct Env<'a> { x: &'a mut &'a mut isize }
/// let mut z = 3;
/// let x: &mut isize = &mut z;
/// let y = (&mut Env { x: &mut x }, fn_ptr); // changed from &x to &mut x
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
/// ```
/// Now the assignment to `**env.x` is legal, but creating a
/// mutable pointer to `x` is not because `x` is not mutable. We
/// could fix this by declaring `x` as `let mut x`. This is ok in
@ -1016,7 +1019,7 @@ pub struct LocalDecl<'tcx> {
/// ```
/// fn foo(x: &str) {
/// match {
/// match x.parse().unwrap() {
/// match x.parse::<u32>().unwrap() {
/// y => y + 2
/// }
/// } {
@ -1690,9 +1693,9 @@ pub enum StatementKind<'tcx> {
/// Encodes a user's type ascription. These need to be preserved
/// intact so that NLL can respect them. For example:
///
/// let a: T = y;
///
/// ```ignore (illustrative)
/// let a: T = y;
/// ```
/// The effect of this annotation is to relate the type `T_y` of the place `y`
/// to the user-given type `T`. The effect depends on the specified variance:
///
@ -1985,7 +1988,7 @@ pub enum ProjectionElem<V, T> {
/// These indices are generated by slice patterns. Easiest to explain
/// by example:
///
/// ```
/// ```ignore (illustrative)
/// [X, _, .._, _, _] => { offset: 0, min_length: 4, from_end: false },
/// [_, X, .._, _, _] => { offset: 1, min_length: 4, from_end: false },
/// [_, _, .._, X, _] => { offset: 2, min_length: 4, from_end: true },
@ -3179,7 +3182,7 @@ impl<'tcx> ConstantKind<'tcx> {
///
/// An example:
///
/// ```rust
/// ```ignore (illustrative)
/// struct S<'a>((i32, &'a str), String);
/// let S((_, w): (i32, &'static str), _): S = ...;
/// // ------ ^^^^^^^^^^^^^^^^^^^ (1)

View file

@ -438,7 +438,7 @@ impl<'tcx> CodegenUnitNameBuilder<'tcx> {
///
/// This function will build CGU names of the form:
///
/// ```
/// ```text
/// <crate-name>.<crate-disambiguator>[-in-<local-crate-id>](-<component>)*[.<special-suffix>]
/// <local-crate-id> = <local-crate-name>.<local-crate-disambiguator>
/// ```

View file

@ -202,7 +202,7 @@ pub enum TerminatorKind<'tcx> {
/// This assignment occurs both in the unwind and the regular code paths. The semantics are best
/// explained by the elaboration:
///
/// ```
/// ```ignore (MIR)
/// BB0 {
/// DropAndReplace(P <- V, goto BB1, unwind BB2)
/// }
@ -210,7 +210,7 @@ pub enum TerminatorKind<'tcx> {
///
/// becomes
///
/// ```
/// ```ignore (MIR)
/// BB0 {
/// Drop(P, goto BB1, unwind BB2)
/// }

View file

@ -29,7 +29,7 @@
//!
//! For example, the `super_basic_block_data` method begins like this:
//!
//! ```rust
//! ```ignore (pseudo-rust)
//! fn super_basic_block_data(&mut self,
//! block: BasicBlock,
//! data: & $($mutability)? BasicBlockData<'tcx>) {
@ -1170,10 +1170,10 @@ pub enum NonMutatingUseContext {
AddressOf,
/// Used as base for another place, e.g., `x` in `x.y`. Will not mutate the place.
/// For example, the projection `x.y` is not marked as a mutation in these cases:
///
/// z = x.y;
/// f(&x.y);
///
/// ```ignore (illustrative)
/// z = x.y;
/// f(&x.y);
/// ```
Projection,
}
@ -1199,10 +1199,10 @@ pub enum MutatingUseContext {
AddressOf,
/// Used as base for another place, e.g., `x` in `x.y`. Could potentially mutate the place.
/// For example, the projection `x.y` is marked as a mutation in these cases:
///
/// x.y = ...;
/// f(&mut x.y);
///
/// ```ignore (illustrative)
/// x.y = ...;
/// f(&mut x.y);
/// ```
Projection,
/// Retagging, a "Stacked Borrows" shadow state operation
Retag,

View file

@ -47,7 +47,8 @@ pub enum Reveal {
/// impl. Concretely, that means that the following example will
/// fail to compile:
///
/// ```
/// ```compile_fail,E0308
/// #![feature(specialization)]
/// trait Assoc {
/// type Output;
/// }
@ -57,7 +58,7 @@ pub enum Reveal {
/// }
///
/// fn main() {
/// let <() as Assoc>::Output = true;
/// let x: <() as Assoc>::Output = true;
/// }
/// ```
UserFacing,
@ -515,7 +516,7 @@ pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
/// For example, the obligation may be satisfied by a specific impl (case A),
/// or it may be relative to some bound that is in scope (case B).
///
/// ```
/// ```ignore (illustrative)
/// impl<T:Clone> Clone<T> for Option<T> { ... } // Impl_1
/// impl<T:Clone> Clone<T> for Box<T> { ... } // Impl_2
/// impl Clone for i32 { ... } // Impl_3

View file

@ -180,6 +180,7 @@ pub struct LeafDef {
/// Example:
///
/// ```
/// #![feature(specialization)]
/// trait Tr {
/// fn assoc(&self);
/// }

View file

@ -59,7 +59,7 @@ pub enum PointerCast {
/// sized struct to a dynamically sized one. E.g., `&[i32; 4]` -> `&[i32]` is
/// represented by:
///
/// ```
/// ```ignore (illustrative)
/// Deref(None) -> [i32; 4],
/// Borrow(AutoBorrow::Ref) -> &[i32; 4],
/// Unsize -> &[i32],

View file

@ -82,7 +82,7 @@ bitflags! {
///
/// is essentially represented with [`Ty`] as the following pseudocode:
///
/// ```
/// ```ignore (illustrative)
/// struct S { x }
/// ```
///

View file

@ -293,7 +293,7 @@ pub struct CaptureInfo {
/// let mut t = (0,1);
///
/// let c = || {
/// println!("{t}"); // L1
/// println!("{t:?}"); // L1
/// t.1 = 4; // L2
/// };
/// ```
@ -309,7 +309,7 @@ pub struct CaptureInfo {
/// let x = 5;
///
/// let c = || {
/// let _ = x
/// let _ = x;
/// };
/// ```
///
@ -373,17 +373,19 @@ pub enum BorrowKind {
/// is borrowing or mutating a mutable referent, e.g.:
///
/// ```
/// let x: &mut isize = ...;
/// let mut z = 3;
/// let x: &mut isize = &mut z;
/// let y = || *x += 5;
/// ```
///
/// If we were to try to translate this closure into a more explicit
/// form, we'd encounter an error with the code as written:
///
/// ```
/// struct Env { x: & &mut isize }
/// let x: &mut isize = ...;
/// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
/// ```compile_fail,E0594
/// struct Env<'a> { x: &'a &'a mut isize }
/// let mut z = 3;
/// let x: &mut isize = &mut z;
/// let y = (&mut Env { x: &x }, fn_ptr); // Closure is pair of env and fn
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
/// ```
///
@ -391,10 +393,11 @@ pub enum BorrowKind {
/// in an aliasable location. To solve, you'd have to translate with
/// an `&mut` borrow:
///
/// ```
/// struct Env { x: &mut &mut isize }
/// let x: &mut isize = ...;
/// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
/// ```compile_fail,E0596
/// struct Env<'a> { x: &'a mut &'a mut isize }
/// let mut z = 3;
/// let x: &mut isize = &mut z;
/// let y = (&mut Env { x: &mut x }, fn_ptr); // changed from &x to &mut x
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
/// ```
///

View file

@ -455,12 +455,13 @@ pub struct TypeckResults<'tcx> {
/// # Example
///
/// ```rust
/// # use std::fmt::Debug;
/// fn foo(x: &u32) -> impl Debug { *x }
/// ```
///
/// The function signature here would be:
///
/// ```
/// ```ignore (illustrative)
/// for<'a> fn(&'a u32) -> Foo
/// ```
///
@ -469,7 +470,7 @@ pub struct TypeckResults<'tcx> {
///
/// The *liberated* form of this would be
///
/// ```
/// ```ignore (illustrative)
/// fn(&'a u32) -> u32
/// ```
///

View file

@ -41,7 +41,7 @@
//!
//! For example, if you have `struct S(Ty, U)` where `S: TypeFoldable` and `U:
//! TypeFoldable`, and an instance `S(ty, u)`, it would be visited like so:
//! ```
//! ```text
//! s.visit_with(visitor) calls
//! - s.super_visit_with(visitor) calls
//! - ty.visit_with(visitor) calls
@ -486,13 +486,13 @@ impl<'tcx> TyCtxt<'tcx> {
/// traversed. If we encounter a bound region bound by this
/// binder or one outer to it, it appears free. Example:
///
/// ```
/// for<'a> fn(for<'b> fn(), T)
/// ^ ^ ^ ^
/// | | | | here, would be shifted in 1
/// | | | here, would be shifted in 2
/// | | here, would be `INNERMOST` shifted in by 1
/// | here, initially, binder would be `INNERMOST`
/// ```ignore (illustrative)
/// for<'a> fn(for<'b> fn(), T)
/// // ^ ^ ^ ^
/// // | | | | here, would be shifted in 1
/// // | | | here, would be shifted in 2
/// // | | here, would be `INNERMOST` shifted in by 1
/// // | here, initially, binder would be `INNERMOST`
/// ```
///
/// You see that, initially, *any* bound value is free,

View file

@ -56,7 +56,9 @@ impl<'tcx> TyCtxt<'tcx> {
/// Checks whether a type is visibly uninhabited from a particular module.
///
/// # Example
/// ```rust
/// ```
/// #![feature(never_type)]
/// # fn main() {}
/// enum Void {}
/// mod a {
/// pub mod b {
@ -67,6 +69,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// }
///
/// mod c {
/// use super::Void;
/// pub struct AlsoSecretlyUninhabited {
/// _priv: Void,
/// }
@ -84,7 +87,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// contain `Foo`.
///
/// # Example
/// ```rust
/// ```ignore (illustrative)
/// let foo_result: Result<T, Foo> = ... ;
/// let Ok(t) = foo_result;
/// ```

View file

@ -337,7 +337,7 @@ impl<'tcx> Instance<'tcx> {
/// Returns `Ok(None)` if we cannot resolve `Instance` to a specific instance.
/// For example, in a context like this,
///
/// ```
/// ```ignore (illustrative)
/// fn foo<T: Debug>(t: T) { ... }
/// ```
///

View file

@ -1012,9 +1012,9 @@ impl<'tcx> Predicate<'tcx> {
/// their values.
///
/// Example:
///
/// struct Foo<T, U: Bar<T>> { ... }
///
/// ```ignore (illustrative)
/// struct Foo<T, U: Bar<T>> { ... }
/// ```
/// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
/// `[[], [U:Bar<T>]]`. Now if there were some particular reference
/// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
@ -1072,9 +1072,9 @@ pub struct OpaqueHiddenType<'tcx> {
/// The type variable that represents the value of the opaque type
/// that we require. In other words, after we compile this function,
/// we will be created a constraint like:
///
/// Foo<'a, T> = ?C
///
/// ```ignore (pseudo-rust)
/// Foo<'a, T> = ?C
/// ```
/// where `?C` is the value of this type variable. =) It may
/// naturally refer to the type and lifetime parameters in scope
/// in this function, though ultimately it should only reference
@ -1115,7 +1115,7 @@ rustc_index::newtype_index! {
///
/// To make this more concrete, consider this program:
///
/// ```
/// ```ignore (illustrative)
/// struct Foo { }
/// fn bar<T>(x: T) {
/// let y: for<'a> fn(&'a u8, Foo) = ...;
@ -1154,7 +1154,7 @@ impl UniverseIndex {
/// corresponds to entering a `forall` quantifier. So, for
/// example, suppose we have this type in universe `U`:
///
/// ```
/// ```ignore (illustrative)
/// for<'a> fn(&'a u32)
/// ```
///
@ -1941,7 +1941,7 @@ pub enum ImplOverlapKind {
/// The widely-used version 0.1.0 of the crate `traitobject` had accidentally relied
/// that difference, making what reduces to the following set of impls:
///
/// ```
/// ```compile_fail,(E0119)
/// trait Trait {}
/// impl Trait for dyn Send + Sync {}
/// impl Trait for dyn Sync + Send {}

View file

@ -187,12 +187,14 @@ pub enum TyKind<'tcx> {
/// Looking at the following example, the witness for this generator
/// may end up as something like `for<'a> [Vec<i32>, &'a Vec<i32>]`:
///
/// ```rust
/// ```ignore UNSOLVED (ask @compiler-errors, should this error? can we just swap the yields?)
/// #![feature(generators)]
/// |a| {
/// let x = &vec![3];
/// yield a;
/// yield x[0];
/// }
/// # ;
/// ```
GeneratorWitness(Binder<'tcx, &'tcx List<Ty<'tcx>>>),
@ -276,9 +278,9 @@ impl<'tcx> TyKind<'tcx> {
static_assert_size!(TyKind<'_>, 32);
/// A closure can be modeled as a struct that looks like:
///
/// struct Closure<'l0...'li, T0...Tj, CK, CS, U>(...U);
///
/// ```ignore (illustrative)
/// struct Closure<'l0...'li, T0...Tj, CK, CS, U>(...U);
/// ```
/// where:
///
/// - 'l0...'li and T0...Tj are the generic parameters
@ -295,25 +297,25 @@ static_assert_size!(TyKind<'_>, 32);
/// and the up-var has the type `Foo`, then that field of U will be `&Foo`).
///
/// So, for example, given this function:
///
/// fn foo<'a, T>(data: &'a mut T) {
/// do(|| data.count += 1)
/// }
///
/// ```ignore (illustrative)
/// fn foo<'a, T>(data: &'a mut T) {
/// do(|| data.count += 1)
/// }
/// ```
/// the type of the closure would be something like:
///
/// struct Closure<'a, T, U>(...U);
///
/// ```ignore (illustrative)
/// struct Closure<'a, T, U>(...U);
/// ```
/// Note that the type of the upvar is not specified in the struct.
/// You may wonder how the impl would then be able to use the upvar,
/// if it doesn't know it's type? The answer is that the impl is
/// (conceptually) not fully generic over Closure but rather tied to
/// instances with the expected upvar types:
///
/// impl<'b, 'a, T> FnMut() for Closure<'a, T, (&'b mut &'a mut T,)> {
/// ...
/// }
///
/// ```ignore (illustrative)
/// impl<'b, 'a, T> FnMut() for Closure<'a, T, (&'b mut &'a mut T,)> {
/// ...
/// }
/// ```
/// You can see that the *impl* fully specified the type of the upvar
/// and thus knows full well that `data` has type `&'b mut &'a mut T`.
/// (Here, I am assuming that `data` is mut-borrowed.)
@ -760,9 +762,9 @@ impl<'tcx> UpvarSubsts<'tcx> {
}
/// An inline const is modeled like
///
/// const InlineConst<'l0...'li, T0...Tj, R>: R;
///
/// ```ignore (illustrative)
/// const InlineConst<'l0...'li, T0...Tj, R>: R;
/// ```
/// where:
///
/// - 'l0...'li and T0...Tj are the generic parameters
@ -936,9 +938,9 @@ impl<'tcx> List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>> {
/// A complete reference to a trait. These take numerous guises in syntax,
/// but perhaps the most recognizable form is in a where-clause:
///
/// T: Foo<U>
///
/// ```ignore (illustrative)
/// T: Foo<U>
/// ```
/// This would be represented by a trait-reference where the `DefId` is the
/// `DefId` for the trait `Foo` and the substs define `T` as parameter 0,
/// and `U` as parameter 1.
@ -1012,9 +1014,9 @@ impl<'tcx> PolyTraitRef<'tcx> {
/// An existential reference to a trait, where `Self` is erased.
/// For example, the trait object `Trait<'a, 'b, X, Y>` is:
///
/// exists T. T: Trait<'a, 'b, X, Y>
///
/// ```ignore (illustrative)
/// exists T. T: Trait<'a, 'b, X, Y>
/// ```
/// The substitutions don't include the erased `Self`, only trait
/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
@ -1434,7 +1436,7 @@ impl<'tcx> fmt::Debug for Region<'tcx> {
///
/// In general, the region lattice looks like
///
/// ```
/// ```text
/// static ----------+-----...------+ (greatest)
/// | | |
/// early-bound and | |
@ -1780,14 +1782,14 @@ impl<'tcx> Region<'tcx> {
/// Given an early-bound or free region, returns the `DefId` where it was bound.
/// For example, consider the regions in this snippet of code:
///
/// ```
/// ```ignore (illustrative)
/// impl<'a> Foo {
/// ^^ -- early bound, declared on an impl
/// // ^^ -- early bound, declared on an impl
///
/// fn bar<'b, 'c>(x: &self, y: &'b u32, z: &'c u64) where 'static: 'c
/// ^^ ^^ ^ anonymous, late-bound
/// | early-bound, appears in where-clauses
/// late-bound, appears only in fn args
/// // ^^ ^^ ^ anonymous, late-bound
/// // | early-bound, appears in where-clauses
/// // late-bound, appears only in fn args
/// {..}
/// }
/// ```

View file

@ -687,17 +687,17 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
///
/// ```
/// type Func<A> = fn(A);
/// type MetaFunc = for<'a> fn(Func<&'a i32>)
/// type MetaFunc = for<'a> fn(Func<&'a i32>);
/// ```
///
/// The type `MetaFunc`, when fully expanded, will be
///
/// for<'a> fn(fn(&'a i32))
/// ^~ ^~ ^~~
/// | | |
/// | | DebruijnIndex of 2
/// Binders
///
/// ```ignore (illustrative)
/// for<'a> fn(fn(&'a i32))
/// // ^~ ^~ ^~~
/// // | | |
/// // | | DebruijnIndex of 2
/// // Binders
/// ```
/// Here the `'a` lifetime is bound in the outer function, but appears as an argument of the
/// inner one. Therefore, that appearance will have a DebruijnIndex of 2, because we must skip
/// over the inner binder (remember that we count De Bruijn indices from 1). However, in the
@ -709,17 +709,17 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
///
/// ```
/// type FuncTuple<A> = (A,fn(A));
/// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a i32>)
/// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a i32>);
/// ```
///
/// Here the final type will be:
///
/// for<'a> fn((&'a i32, fn(&'a i32)))
/// ^~~ ^~~
/// | |
/// DebruijnIndex of 1 |
/// DebruijnIndex of 2
///
/// ```ignore (illustrative)
/// for<'a> fn((&'a i32, fn(&'a i32)))
/// // ^~~ ^~~
/// // | |
/// // DebruijnIndex of 1 |
/// // DebruijnIndex of 2
/// ```
/// As indicated in the diagram, here the same type `&'a i32` is substituted once, but in the
/// first case we do not increase the De Bruijn index and in the second case we do. The reason
/// is that only in the second case have we passed through a fn binder.
@ -767,7 +767,7 @@ pub struct UserSubsts<'tcx> {
/// sometimes needed to constrain the type parameters on the impl. For
/// example, in this code:
///
/// ```
/// ```ignore (illustrative)
/// struct Foo<T> { }
/// impl<A> Foo<A> { fn method() { } }
/// ```

View file

@ -975,7 +975,7 @@ impl<'tcx> ExplicitSelf<'tcx> {
///
/// Examples:
///
/// ```
/// ```ignore (illustrative)
/// impl<'a> Foo for &'a T {
/// // Legal declarations:
/// fn method1(self: &&'a T); // ExplicitSelf::ByReference

View file

@ -34,7 +34,7 @@ impl<'tcx> TypeWalker<'tcx> {
///
/// Example: Imagine you are walking `Foo<Bar<i32>, usize>`.
///
/// ```
/// ```ignore (illustrative)
/// let mut iter: TypeWalker = ...;
/// iter.next(); // yields Foo
/// iter.next(); // yields Bar<i32>