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:
commit
574830f573
116 changed files with 668 additions and 609 deletions
|
@ -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
|
||||
|
|
|
@ -371,7 +371,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// ```ignore (illustrative)
|
||||
/// fn with_closure<F>(_: F)
|
||||
/// where F: Fn(&u32) -> &u32 { .. }
|
||||
///
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
/// }
|
||||
|
|
|
@ -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
|
||||
/// }
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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> { ... }
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */ }
|
||||
//! ```
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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`,
|
||||
|
|
|
@ -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`.
|
||||
///
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue