1
Fork 0

Auto merge of #96094 - Elliot-Roberts:fix_doctests, r=compiler-errors

Begin fixing all the broken doctests in `compiler/`

Begins to fix #95994.
All of them pass now but 24 of them I've marked with `ignore HELP (<explanation>)` (asking for help) as I'm unsure how to get them to work / if we should leave them as they are.
There are also a few that I marked `ignore` that could maybe be made to work but seem less important.
Each `ignore` has a rough "reason" for ignoring after it parentheses, with

- `(pseudo-rust)` meaning "mostly rust-like but contains foreign syntax"
- `(illustrative)` a somewhat catchall for either a fragment of rust that doesn't stand on its own (like a lone type), or abbreviated rust with ellipses and undeclared types that would get too cluttered if made compile-worthy.
- `(not-rust)` stuff that isn't rust but benefits from the syntax highlighting, like MIR.
- `(internal)` uses `rustc_*` code which would be difficult to make work with the testing setup.

Those reason notes are a bit inconsistently applied and messy though. If that's important I can go through them again and try a more principled approach. When I run `rg '```ignore \(' .` on the repo, there look to be lots of different conventions other people have used for this sort of thing. I could try unifying them all if that would be helpful.

I'm not sure if there was a better existing way to do this but I wrote my own script to help me run all the doctests and wade through the output. If that would be useful to anyone else, I put it here: https://github.com/Elliot-Roberts/rust_doctest_fixing_tool
This commit is contained in:
bors 2022-05-07 06:30:29 +00:00
commit 574830f573
116 changed files with 668 additions and 609 deletions

View file

@ -294,9 +294,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
///
/// Example:
///
/// ```
/// T: std::ops::Index<usize, Output = u32>
/// ^1 ^^^^^^^^^^^^^^2 ^^^^3 ^^^^^^^^^^^4
/// ```ignore (illustrative)
/// T: std::ops::Index<usize, Output = u32>
/// // ^1 ^^^^^^^^^^^^^^2 ^^^^3 ^^^^^^^^^^^4
/// ```
///
/// 1. The `self_ty` here would refer to the type `T`.
@ -310,7 +310,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
///
/// For (generic) associated types
///
/// ```
/// ```ignore (illustrative)
/// <Vec<u8> as Iterable<u8>>::Iter::<'a>
/// ```
///
@ -756,7 +756,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
///
/// Example:
///
/// ```
/// ```ignore (illustrative)
/// poly_trait_ref = Iterator<Item = u32>
/// self_ty = Foo
/// ```
@ -1021,10 +1021,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
///
/// Example:
///
/// ```
/// ```ignore (illustrative)
/// fn foo<T: Bar + Baz>() { }
/// ^ ^^^^^^^^^ ast_bounds
/// param_ty
/// // ^ ^^^^^^^^^ ast_bounds
/// // param_ty
/// ```
///
/// The `sized_by_default` parameter indicates if, in this context, the `param_ty` should be

View file

@ -371,7 +371,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
///
/// # Examples
///
/// ```
/// ```ignore (illustrative)
/// fn with_closure<F>(_: F)
/// where F: Fn(&u32) -> &u32 { .. }
///

View file

@ -21,7 +21,7 @@
//! When inferring the generic arguments of functions, the argument
//! order is relevant, which can lead to the following edge case:
//!
//! ```rust
//! ```ignore (illustrative)
//! fn foo<T>(a: T, b: T) {
//! // ...
//! }
@ -1210,7 +1210,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
///
/// Example:
///
/// ```
/// ```ignore (illustrative)
/// let mut coerce = CoerceMany::new(expected_ty);
/// for expr in exprs {
/// let expr_ty = fcx.check_expr_with_expectation(expr, expected);

View file

@ -439,7 +439,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Identify some cases where `as_ref()` would be appropriate and suggest it.
///
/// Given the following code:
/// ```
/// ```compile_fail,E0308
/// struct Foo;
/// fn takes_ref(_: &Foo) {}
/// let ref opt = Some(Foo);
@ -449,7 +449,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Suggest using `opt.as_ref().map(|param| takes_ref(param));` instead.
///
/// It only checks for `Option` and `Result` and won't work with
/// ```
/// ```ignore (illustrative)
/// opt.map(|param| { takes_ref(param) });
/// ```
fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Span, &'static str, String)> {
@ -566,7 +566,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// This function is used to determine potential "simple" improvements or users' errors and
/// provide them useful help. For example:
///
/// ```
/// ```compile_fail,E0308
/// fn some_fn(s: &str) {}
///
/// let x = "hey!".to_owned();

View file

@ -144,6 +144,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
/// code. The most common case is something like this:
///
/// ```rust
/// # fn foo() -> i32 { 4 }
/// match foo() {
/// 22 => Default::default(), // call this type `?D`
/// _ => return, // return has type `!`
@ -168,7 +169,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
/// fallback to use based on whether there is a coercion pattern
/// like this:
///
/// ```
/// ```ignore (not-rust)
/// ?Diverging -> ?V
/// ?NonDiverging -> ?V
/// ?V != ?NonDiverging

View file

@ -1475,7 +1475,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// A common error is to add an extra semicolon:
///
/// ```
/// ```compile_fail,E0308
/// fn foo() -> usize {
/// 22;
/// }

View file

@ -72,7 +72,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// When encountering an fn-like ctor that needs to unify with a value, check whether calling
/// the ctor would successfully solve the type mismatch and if so, suggest it:
/// ```
/// ```compile_fail,E0308
/// fn foo(x: usize) -> usize { x }
/// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
/// ```
@ -463,7 +463,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// A common error is to forget to add a semicolon at the end of a block, e.g.,
///
/// ```
/// ```compile_fail,E0308
/// # fn bar_that_returns_u32() -> u32 { 4 }
/// fn foo() {
/// bar_that_returns_u32()
/// }
@ -504,7 +505,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// A possible error is to forget to add a return type that is needed:
///
/// ```
/// ```compile_fail,E0308
/// # fn bar_that_returns_u32() -> u32 { 4 }
/// fn foo() {
/// bar_that_returns_u32()
/// }
@ -569,7 +571,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// check whether the return type is a generic type with a trait bound
/// only suggest this if the generic param is not present in the arguments
/// if this is true, hint them towards changing the return type to `impl Trait`
/// ```
/// ```compile_fail,E0308
/// fn cant_name_it<T: Fn() -> u32>() -> T {
/// || 3
/// }

View file

@ -71,7 +71,7 @@ pub(super) fn build_control_flow_graph<'tcx>(
/// ```
///
/// Rule 3:
/// ```rust
/// ```compile_fail,E0382
/// let mut a = (vec![0], vec![0]);
/// drop(a);
/// a.1 = vec![1];

View file

@ -17,11 +17,11 @@ use std::cell::RefCell;
use std::ops::Deref;
/// Closures defined within the function. For example:
///
/// fn foo() {
/// bar(move|| { ... })
/// }
///
/// ```ignore (illustrative)
/// fn foo() {
/// bar(move|| { ... })
/// }
/// ```
/// Here, the function `foo()` and the closure passed to
/// `bar()` will each have their own `FnCtxt`, but they will
/// share the inherited fields.

View file

@ -201,8 +201,9 @@ pub struct Pick<'tcx> {
pub import_ids: SmallVec<[LocalDefId; 1]>,
/// Indicates that the source expression should be autoderef'd N times
///
/// A = expr | *expr | **expr | ...
/// ```ignore (not-rust)
/// A = expr | *expr | **expr | ...
/// ```
pub autoderefs: usize,
/// Indicates that we want to add an autoref (and maybe also unsize it), or if the receiver is
@ -1638,7 +1639,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
///
/// Example (`src/test/ui/method-two-trait-defer-resolution-1.rs`):
///
/// ```
/// ```ignore (illustrative)
/// trait Foo { ... }
/// impl Foo for Vec<i32> { ... }
/// impl Foo for Vec<usize> { ... }

View file

@ -890,16 +890,19 @@ fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
/// Tupling means that all call-side arguments are packed into a tuple and
/// passed as a single parameter. For example, if tupling is enabled, this
/// function:
///
/// fn f(x: (isize, isize))
///
/// ```
/// fn f(x: (isize, isize)) {}
/// ```
/// Can be called as:
///
/// f(1, 2);
///
/// ```ignore UNSOLVED (can this be done in user code?)
/// # fn f(x: (isize, isize)) {}
/// f(1, 2);
/// ```
/// Instead of:
///
/// f((1, 2));
/// ```
/// # fn f(x: (isize, isize)) {}
/// f((1, 2));
/// ```
#[derive(Clone, Eq, PartialEq)]
enum TupleArgumentsFlag {
DontTupleArguments,

View file

@ -1894,7 +1894,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
///
/// Syntactically, these look like `[pat_0, ..., pat_n]`.
/// Semantically, we are type checking a pattern with structure:
/// ```
/// ```ignore (not-rust)
/// [before_0, ..., before_n, (slice, after_0, ... after_n)?]
/// ```
/// The type of `slice`, if it is present, depends on the `expected` type.

View file

@ -269,7 +269,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
///
/// Consider this silly example:
///
/// ```
/// ```ignore UNSOLVED (does replacing @i32 with Box<i32> preserve the desired semantics for the example?)
/// fn borrow(x: &i32) -> &i32 {x}
/// fn foo(x: @i32) -> i32 { // block: B
/// let b = borrow(x); // region: <R0>

View file

@ -5,9 +5,9 @@
//! immutable "borrow kind" (see `ty::BorrowKind` for details) and then
//! "escalating" the kind as needed. The borrow kind proceeds according to
//! the following lattice:
//!
//! ty::ImmBorrow -> ty::UniqueImmBorrow -> ty::MutBorrow
//!
//! ```ignore (not-rust)
//! ty::ImmBorrow -> ty::UniqueImmBorrow -> ty::MutBorrow
//! ```
//! So, for example, if we see an assignment `x = 5` to an upvar `x`, we
//! will promote its borrow kind to mutable borrow. If we see an `&mut x`
//! we'll do the same. Naturally, this applies not just to the upvar, but
@ -447,16 +447,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// the existing min_capture map that is stored in TypeckResults.
///
/// Eg:
/// ```rust,no_run
/// ```
/// #[derive(Debug)]
/// struct Point { x: i32, y: i32 }
///
/// let s: String; // hir_id_s
/// let mut p: Point; // his_id_p
/// let s = String::from("s"); // hir_id_s
/// let mut p = Point { x: 2, y: -2 }; // his_id_p
/// let c = || {
/// println!("{s}"); // L1
/// println!("{s:?}"); // L1
/// p.x += 10; // L2
/// println!("{}" , p.y); // L3
/// println!("{p}"); // L4
/// println!("{p:?}"); // L4
/// drop(s); // L5
/// };
/// ```
@ -465,7 +466,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
///
/// InferBorrowKind results in a structure like this:
///
/// ```text
/// ```ignore (illustrative)
/// {
/// Place(base: hir_id_s, projections: [], ....) -> {
/// capture_kind_expr: hir_id_L5,
@ -487,10 +488,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// path_expr_id: hir_id_L4,
/// capture_kind: ByValue
/// },
/// }
/// ```
///
/// After the min capture analysis, we get:
/// ```text
/// ```ignore (illustrative)
/// {
/// hir_id_s -> [
/// Place(base: hir_id_s, projections: [], ....) -> {
@ -506,6 +508,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// capture_kind: ByValue
/// },
/// ],
/// }
/// ```
fn compute_min_captures(
&self,
@ -1285,27 +1288,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// - Ty(place): Type of place
/// - `(a, b)`: Represents the function parameters `base_path_ty` and `captured_by_move_projs`
/// respectively.
/// ```
/// ```ignore (illustrative)
/// (Ty(w), [ &[p, x], &[c] ])
/// |
/// ----------------------------
/// | |
/// v v
/// // |
/// // ----------------------------
/// // | |
/// // v v
/// (Ty(w.p), [ &[x] ]) (Ty(w.c), [ &[] ]) // I(1)
/// | |
/// v v
/// // | |
/// // v v
/// (Ty(w.p), [ &[x] ]) false
/// |
/// |
/// -------------------------------
/// | |
/// v v
/// // |
/// // |
/// // -------------------------------
/// // | |
/// // v v
/// (Ty((w.p).x), [ &[] ]) (Ty((w.p).y), []) // IMP 2
/// | |
/// v v
/// // | |
/// // v v
/// false NeedsSignificantDrop(Ty(w.p.y))
/// |
/// v
/// // |
/// // v
/// true
/// ```
///
@ -1323,7 +1326,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
///
/// Consider another example:
///
/// ```rust
/// ```ignore (pseudo-rust)
/// struct X;
/// impl Drop for X {}
///
@ -1728,14 +1731,14 @@ struct InferBorrowKind<'a, 'tcx> {
/// s.str2 via a MutableBorrow
///
/// ```rust,no_run
/// struct SomeStruct { str1: String, str2: String }
/// struct SomeStruct { str1: String, str2: String };
///
/// // Assume that the HirId for the variable definition is `V1`
/// let mut s = SomeStruct { str1: format!("s1"), str2: format!("s2") }
/// let mut s = SomeStruct { str1: format!("s1"), str2: format!("s2") };
///
/// let fix_s = |new_s2| {
/// // Assume that the HirId for the expression `s.str1` is `E1`
/// println!("Updating SomeStruct with str1=", s.str1);
/// println!("Updating SomeStruct with str1={0}", s.str1);
/// // Assume that the HirId for the expression `*s.str2` is `E2`
/// s.str2 = new_s2;
/// };
@ -1743,7 +1746,7 @@ struct InferBorrowKind<'a, 'tcx> {
///
/// For closure `fix_s`, (at a high level) the map contains
///
/// ```
/// ```ignore (illustrative)
/// Place { V1, [ProjectionKind::Field(Index=0, Variant=0)] } : CaptureKind { E1, ImmutableBorrow }
/// Place { V1, [ProjectionKind::Field(Index=1, Variant=0)] } : CaptureKind { E2, MutableBorrow }
/// ```
@ -2071,7 +2074,7 @@ fn migration_suggestion_for_2229(
/// Consider the following example
/// ```rust,no_run
/// struct Point { x: i32, y: i32 }
/// let mut p: Point { x: 10, y: 10 };
/// let mut p = Point { x: 10, y: 10 };
///
/// let c = || {
/// p.x += 10;
@ -2217,7 +2220,10 @@ fn determine_place_ancestry_relation<'tcx>(
///
/// Reason we only drop the last deref is because of the following edge case:
///
/// ```rust
/// ```
/// # struct A { field_of_a: Box<i32> }
/// # struct B {}
/// # struct C<'a>(&'a i32);
/// struct MyStruct<'a> {
/// a: &'static A,
/// b: B,
@ -2225,7 +2231,7 @@ fn determine_place_ancestry_relation<'tcx>(
/// }
///
/// fn foo<'a, 'b>(m: &'a MyStruct<'b>) -> impl FnMut() + 'static {
/// let c = || drop(&*m.a.field_of_a);
/// || drop(&*m.a.field_of_a)
/// // Here we really do want to capture `*m.a` because that outlives `'static`
///
/// // If we capture `m`, then the closure no longer outlives `'static'

View file

@ -37,7 +37,7 @@ use std::ops::ControlFlow;
/// Helper type of a temporary returned by `.for_item(...)`.
/// This is necessary because we can't write the following bound:
///
/// ```rust
/// ```ignore (illustrative)
/// F: for<'b, 'tcx> where 'tcx FnOnce(FnCtxt<'b, 'tcx>)
/// ```
struct CheckWfFcxBuilder<'tcx> {

View file

@ -531,7 +531,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
/// In particular, definitions of opaque types can only use other generics as arguments,
/// and they cannot repeat an argument. Example:
///
/// ```rust
/// ```ignore (illustrative)
/// type Foo<A, B> = impl Bar<A, B>;
///
/// // Okay -- `Foo` is applied to two distinct, generic types.

View file

@ -109,9 +109,9 @@ pub fn identify_constrained_generic_params<'tcx>(
/// constrained before it is used, if that is possible, and add the
/// parameters so constrained to `input_parameters`. For example,
/// imagine the following impl:
///
/// impl<T: Debug, U: Iterator<Item = T>> Trait for U
///
/// ```ignore (illustrative)
/// impl<T: Debug, U: Iterator<Item = T>> Trait for U
/// ```
/// The impl's predicates are collected from left to right. Ignoring
/// the implicit `Sized` bounds, these are
/// * T: Debug

View file

@ -698,12 +698,13 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
/// In the following example the closures `c` only captures `p.x` even though `incr`
/// is a capture of the nested closure
///
/// ```rust,ignore(cannot-test-this-because-pseudo-code)
/// let p = ..;
/// ```
/// struct P { x: i32 }
/// let mut p = P { x: 4 };
/// let c = || {
/// let incr = 10;
/// let nested = || p.x += incr;
/// }
/// };
/// ```
///
/// - When reporting the Place back to the Delegate, ensure that the UpvarId uses the enclosing

View file

@ -29,7 +29,7 @@
//!
//! Suppose we have the following always applicable impl:
//!
//! ```rust
//! ```ignore (illustrative)
//! impl<T> SpecExtend<T> for std::vec::IntoIter<T> { /* specialized impl */ }
//! impl<T, I: Iterator<Item=T>> SpecExtend<T> for I { /* default impl */ }
//! ```

View file

@ -9,12 +9,12 @@
//! expressions of the following forms (the actual enum has many more
//! possibilities, naturally, but they are all variants of these base
//! forms):
//!
//! E = rvalue // some computed rvalue
//! | x // address of a local variable or argument
//! | *E // deref of a ptr
//! | E.comp // access to an interior component
//!
//! ```ignore (not-rust)
//! E = rvalue // some computed rvalue
//! | x // address of a local variable or argument
//! | *E // deref of a ptr
//! | E.comp // access to an interior component
//! ```
//! Imagine a routine ToAddr(Expr) that evaluates an expression and returns an
//! address where the result is to be found. If Expr is a place, then this
//! is the address of the place. If `Expr` is an rvalue, this is the address of

View file

@ -211,15 +211,15 @@ fn insert_required_predicates_to_be_wf<'tcx>(
/// We also have to check the explicit predicates
/// declared on the type.
/// ```ignore (illustrative)
/// struct Foo<'a, T> {
/// field1: Bar<T>
/// }
///
/// struct Foo<'a, T> {
/// field1: Bar<T>
/// }
///
/// struct Bar<U> where U: 'static, U: Foo {
/// ...
/// }
///
/// struct Bar<U> where U: 'static, U: Foo {
/// ...
/// }
/// ```
/// Here, we should fetch the explicit predicates, which
/// will give us `U: 'static` and `U: Foo`. The latter we
/// can ignore, but we will want to process `U: 'static`,

View file

@ -26,9 +26,9 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
/// calling that fn, and hence the *callee* can assume that its
/// argument types are well-formed. This may imply certain relationships
/// between generic parameters. For example:
///
/// fn foo<'a,T>(x: &'a T)
///
/// ```
/// fn foo<'a,T>(x: &'a T) {}
/// ```
/// can only be called with a `'a` and `T` such that `&'a T` is WF.
/// For `&'a T` to be WF, `T: 'a` must hold. So we can assume `T: 'a`.
///

View file

@ -34,11 +34,11 @@ pub struct Constraint<'a> {
/// To build constraints, we visit one item (type, trait) at a time
/// and look at its contents. So e.g., if we have
///
/// struct Foo<T> {
/// b: Bar<T>
/// }
///
/// ```ignore (illustrative)
/// struct Foo<T> {
/// b: Bar<T>
/// }
/// ```
/// then while we are visiting `Bar<T>`, the `CurrentItem` would have
/// the `DefId` and the start of `Foo`'s inferreds.
pub struct CurrentItem {