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

@ -573,7 +573,7 @@ pub struct Block {
pub span: Span,
pub tokens: Option<LazyTokenStream>,
/// The following *isn't* a parse error, but will cause multiple errors in following stages.
/// ```
/// ```compile_fail
/// let x = {
/// foo: var
/// };

View file

@ -615,7 +615,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
/// Desugar `<expr>.await` into:
/// ```rust
/// ```ignore (pseudo-rust)
/// match ::std::future::IntoFuture::into_future(<expr>) {
/// mut __awaitee => loop {
/// match unsafe { ::std::future::Future::poll(
@ -1325,7 +1325,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
/// Desugar `ExprForLoop` from: `[opt_ident]: for <pat> in <head> <body>` into:
/// ```rust
/// ```ignore (pseudo-rust)
/// {
/// let result = match IntoIterator::into_iter(<head>) {
/// mut iter => {
@ -1436,7 +1436,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
/// Desugar `ExprKind::Try` from: `<expr>?` into:
/// ```rust
/// ```ignore (pseudo-rust)
/// match Try::branch(<expr>) {
/// ControlFlow::Continue(val) => #[allow(unreachable_code)] val,,
/// ControlFlow::Break(residual) =>

View file

@ -934,7 +934,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
/// Given an associated type constraint like one of these:
///
/// ```
/// ```ignore (illustrative)
/// T: Iterator<Item: Debug>
/// ^^^^^^^^^^^
/// T: Iterator<Item = Debug>

View file

@ -68,20 +68,20 @@
//! will be made to flow subsequent breaks together onto lines. Inconsistent
//! is the opposite. Inconsistent breaking example would be, say:
//!
//! ```
//! ```ignore (illustrative)
//! foo(hello, there, good, friends)
//! ```
//!
//! breaking inconsistently to become
//!
//! ```
//! ```ignore (illustrative)
//! foo(hello, there,
//! good, friends);
//! ```
//!
//! whereas a consistent breaking would yield:
//!
//! ```
//! ```ignore (illustrative)
//! foo(hello,
//! there,
//! good,
@ -153,14 +153,14 @@ enum IndentStyle {
/// Vertically aligned under whatever column this block begins at.
///
/// fn demo(arg1: usize,
/// arg2: usize);
/// arg2: usize) {}
Visual,
/// Indented relative to the indentation level of the previous line.
///
/// fn demo(
/// arg1: usize,
/// arg2: usize,
/// );
/// ) {}
Block { offset: isize },
}

View file

@ -896,20 +896,23 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
///
/// In the simplest case, where there are no unions involved, if a mutable borrow of `x` is
/// attempted while a shared borrow is live, then this function will return:
///
/// ("x", "", "")
///
/// ```
/// ("x", "", "")
/// # ;
/// ```
/// In the simple union case, if a mutable borrow of a union field `x.z` is attempted while
/// a shared borrow of another field `x.y`, then this function will return:
///
/// ("x", "x.z", "x.y")
///
/// ```
/// ("x", "x.z", "x.y")
/// # ;
/// ```
/// In the more complex union case, where the union is a field of a struct, then if a mutable
/// borrow of a union field in a struct `x.u.z` is attempted while a shared borrow of
/// another field `x.u.y`, then this function will return:
///
/// ("x.u", "x.u.z", "x.u.y")
///
/// ```
/// ("x.u", "x.u.z", "x.u.y")
/// # ;
/// ```
/// This is used when creating error messages like below:
///
/// ```text

View file

@ -259,7 +259,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
/// Report an error because the universal region `fr` was required to outlive
/// `outlived_fr` but it is not known to do so. For example:
///
/// ```
/// ```compile_fail,E0312
/// fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x }
/// ```
///

View file

@ -210,7 +210,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
/// Suppose we are trying to give a name to the lifetime of the
/// reference `x`:
///
/// ```
/// ```ignore (pseudo-rust)
/// fn foo(x: &u32) { .. }
/// ```
///
@ -746,7 +746,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
/// e.g. given the function:
///
/// ```
/// async fn foo() -> i32 {}
/// async fn foo() -> i32 { 2 }
/// ```
///
/// this function, given the lowered return type of `foo`, an [`OpaqueDef`] that implements `Future<Output=i32>`,

View file

@ -169,7 +169,7 @@ where
/// Returns the "choice regions" for a given member
/// constraint. This is the `R1..Rn` from a constraint like:
///
/// ```
/// ```text
/// R0 member of [R1..Rn]
/// ```
crate fn choice_regions(&self, pci: NllMemberConstraintIndex) -> &[ty::RegionVid] {
@ -195,14 +195,14 @@ where
///
/// Before:
///
/// ```
/// ```text
/// target_list: A -> B -> C -> (None)
/// source_list: D -> E -> F -> (None)
/// ```
///
/// After:
///
/// ```
/// ```text
/// target_list: A -> B -> C -> D -> E -> F -> (None)
/// ```
fn append_list(

View file

@ -436,14 +436,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// minimum values.
///
/// For example:
///
/// fn foo<'a, 'b>(..) where 'a: 'b
///
/// ```
/// fn foo<'a, 'b>( /* ... */ ) where 'a: 'b { /* ... */ }
/// ```
/// would initialize two variables like so:
///
/// R0 = { CFG, R0 } // 'a
/// R1 = { CFG, R0, R1 } // 'b
///
/// ```ignore (illustrative)
/// R0 = { CFG, R0 } // 'a
/// R1 = { CFG, R0, R1 } // 'b
/// ```
/// Here, R0 represents `'a`, and it contains (a) the entire CFG
/// and (b) any universally quantified regions that it outlives,
/// which in this case is just itself. R1 (`'b`) in contrast also
@ -1310,9 +1310,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// whether any of the constraints were too strong. In particular,
/// we want to check for a case where a universally quantified
/// region exceeded its bounds. Consider:
///
/// fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x }
///
/// ```compile_fail,E0312
/// fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x }
/// ```
/// In this case, returning `x` requires `&'a u32 <: &'b u32`
/// and hence we establish (transitively) a constraint that
/// `'a: 'b`. The `propagate_constraints` code above will
@ -1366,9 +1366,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// <https://smallcultfollowing.com/babysteps/blog/2019/01/17/polonius-and-region-errors/>
///
/// In the canonical example
///
/// fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x }
///
/// ```compile_fail,E0312
/// fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x }
/// ```
/// returning `x` requires `&'a u32 <: &'b u32` and hence we establish (transitively) a
/// constraint that `'a: 'b`. It is an error that we have no evidence that this
/// constraint holds.

View file

@ -971,7 +971,7 @@ pub enum Locations {
/// things like the type of the return slot. Consider this
/// example:
///
/// ```
/// ```compile_fail,E0515
/// fn foo<'a>(x: &'a u32) -> &'a u32 {
/// let y = 22;
/// return &y; // error

View file

@ -187,12 +187,12 @@ pub enum RegionClassification {
///
/// Consider this example:
///
/// ```
/// ```ignore (pseudo-rust)
/// fn foo<'a, 'b>(a: &'a u32, b: &'b u32, c: &'static u32) {
/// let closure = for<'x> |x: &'x u32| { .. };
/// ^^^^^^^ pretend this were legal syntax
/// for declaring a late-bound region in
/// a closure signature
/// // ^^^^^^^ pretend this were legal syntax
/// // for declaring a late-bound region in
/// // a closure signature
/// }
/// ```
///

View file

@ -5,14 +5,14 @@
//!
//! For example, a type like:
//!
//! ```
//! ```ignore (old code)
//! #[derive(RustcEncodable, RustcDecodable)]
//! struct Node { id: usize }
//! ```
//!
//! would generate two implementations like:
//!
//! ```
//! ```ignore (old code)
//! # struct Node { id: usize }
//! impl<S: Encoder<E>, E> Encodable<S, E> for Node {
//! fn encode(&self, s: &mut S) -> Result<(), E> {
@ -40,7 +40,7 @@
//! Other interesting scenarios are when the item has type parameters or
//! references other non-built-in types. A type definition like:
//!
//! ```
//! ```ignore (old code)
//! # #[derive(RustcEncodable, RustcDecodable)]
//! # struct Span;
//! #[derive(RustcEncodable, RustcDecodable)]
@ -49,7 +49,7 @@
//!
//! would yield functions like:
//!
//! ```
//! ```ignore (old code)
//! # #[derive(RustcEncodable, RustcDecodable)]
//! # struct Span;
//! # struct Spanned<T> { node: T, span: Span }

View file

@ -1006,9 +1006,11 @@ impl<'a> MethodDef<'a> {
/// }
/// }
/// }
///
/// // or if A is repr(packed) - note fields are matched by-value
/// // instead of by-reference.
/// ```
/// or if A is repr(packed) - note fields are matched by-value
/// instead of by-reference.
/// ```
/// # struct A { x: i32, y: i32 }
/// impl PartialEq for A {
/// fn eq(&self, other: &A) -> bool {
/// match *self {
@ -1126,14 +1128,15 @@ impl<'a> MethodDef<'a> {
/// // is equivalent to
///
/// impl PartialEq for A {
/// fn eq(&self, other: &A) -> ::bool {
/// fn eq(&self, other: &A) -> bool {
/// use A::*;
/// match (&*self, &*other) {
/// (&A1, &A1) => true,
/// (&A2(ref self_0),
/// &A2(ref __arg_1_0)) => (*self_0).eq(&(*__arg_1_0)),
/// _ => {
/// let __self_vi = match *self { A1(..) => 0, A2(..) => 1 };
/// let __arg_1_vi = match *other { A1(..) => 0, A2(..) => 1 };
/// let __self_vi = match *self { A1 => 0, A2(..) => 1 };
/// let __arg_1_vi = match *other { A1 => 0, A2(..) => 1 };
/// false
/// }
/// }

View file

@ -249,7 +249,7 @@ fn generate_test_harness(
///
/// By default this expands to
///
/// ```
/// ```ignore UNSOLVED (I think I still need guidance for this one. Is it correct? Do we try to make it run? How do we nicely fill it out?)
/// #[rustc_main]
/// pub fn main() {
/// extern crate test;

View file

@ -396,15 +396,15 @@ impl Drop for Linker<'_> {
///
/// At a high level Thin LTO looks like:
///
/// 1. Prepare a "summary" of each LLVM module in question which describes
/// the values inside, cost of the values, etc.
/// 2. Merge the summaries of all modules in question into one "index"
/// 3. Perform some global analysis on this index
/// 4. For each module, use the index and analysis calculated previously to
/// perform local transformations on the module, for example inlining
/// small functions from other modules.
/// 5. Run thin-specific optimization passes over each module, and then code
/// generate everything at the end.
/// 1. Prepare a "summary" of each LLVM module in question which describes
/// the values inside, cost of the values, etc.
/// 2. Merge the summaries of all modules in question into one "index"
/// 3. Perform some global analysis on this index
/// 4. For each module, use the index and analysis calculated previously to
/// perform local transformations on the module, for example inlining
/// small functions from other modules.
/// 5. Run thin-specific optimization passes over each module, and then code
/// generate everything at the end.
///
/// The summary for each module is intended to be quite cheap, and the global
/// index is relatively quite cheap to create as well. As a result, the goal of

View file

@ -27,9 +27,9 @@ The module is thus driven from an outside client with functions like
Internally the module will try to reuse already created metadata by
utilizing a cache. The way to get a shared metadata node when needed is
thus to just call the corresponding function in this module:
let file_metadata = file_metadata(cx, file);
```ignore (illustrative)
let file_metadata = file_metadata(cx, file);
```
The function will take care of probing the cache for an existing node for
that exact file path.
@ -63,7 +63,7 @@ struct List {
will generate the following callstack with a naive DFS algorithm:
```
```ignore (illustrative)
describe(t = List)
describe(t = i32)
describe(t = Option<Box<List>>)

View file

@ -23,7 +23,8 @@
//! `computed` does not change accidentally (e.g. somebody might accidentally call
//! `foo.computed.mutate()`). This is what `Frozen` is for. We can do the following:
//!
//! ```rust
//! ```
//! # struct Bar {}
//! use rustc_data_structures::frozen::Frozen;
//!
//! struct Foo {

View file

@ -202,7 +202,7 @@ impl<O> Node<O> {
/// with this node.
///
/// The non-`Error` state transitions are as follows.
/// ```
/// ```text
/// (Pre-creation)
/// |
/// | register_obligation_at() (called by process_obligations() and

View file

@ -25,9 +25,8 @@ of the reference because the backing allocation of the vector does not change.
This library enables this safe usage by keeping the owner and the reference
bundled together in a wrapper type that ensure that lifetime constraint:
```rust
# extern crate owning_ref;
# use owning_ref::OwningRef;
```
# use rustc_data_structures::owning_ref::OwningRef;
# fn main() {
fn return_owned_and_referenced() -> OwningRef<Vec<u8>, [u8]> {
let v = vec![1, 2, 3, 4];
@ -56,8 +55,7 @@ See the documentation around `OwningHandle` for more details.
## Basics
```
extern crate owning_ref;
use owning_ref::BoxRef;
use rustc_data_structures::owning_ref::BoxRef;
fn main() {
// Create an array owned by a Box.
@ -78,8 +76,7 @@ fn main() {
## Caching a reference to a struct field
```
extern crate owning_ref;
use owning_ref::BoxRef;
use rustc_data_structures::owning_ref::BoxRef;
fn main() {
struct Foo {
@ -106,8 +103,7 @@ fn main() {
## Caching a reference to an entry in a vector
```
extern crate owning_ref;
use owning_ref::VecRef;
use rustc_data_structures::owning_ref::VecRef;
fn main() {
let v = VecRef::new(vec![1, 2, 3, 4, 5]).map(|v| &v[3]);
@ -118,8 +114,7 @@ fn main() {
## Caching a subslice of a String
```
extern crate owning_ref;
use owning_ref::StringRef;
use rustc_data_structures::owning_ref::StringRef;
fn main() {
let s = StringRef::new("hello world".to_owned())
@ -132,8 +127,7 @@ fn main() {
## Reference counted slices that share ownership of the backing storage
```
extern crate owning_ref;
use owning_ref::RcRef;
use rustc_data_structures::owning_ref::RcRef;
use std::rc::Rc;
fn main() {
@ -155,8 +149,7 @@ fn main() {
## Atomic reference counted slices that share ownership of the backing storage
```
extern crate owning_ref;
use owning_ref::ArcRef;
use rustc_data_structures::owning_ref::ArcRef;
use std::sync::Arc;
fn main() {
@ -188,8 +181,7 @@ fn main() {
## References into RAII locks
```
extern crate owning_ref;
use owning_ref::RefRef;
use rustc_data_structures::owning_ref::RefRef;
use std::cell::{RefCell, Ref};
fn main() {
@ -219,8 +211,7 @@ When the owned container implements `DerefMut`, it is also possible to make
a _mutable owning reference_. (e.g., with `Box`, `RefMut`, `MutexGuard`)
```
extern crate owning_ref;
use owning_ref::RefMutRefMut;
use rustc_data_structures::owning_ref::RefMutRefMut;
use std::cell::{RefCell, RefMut};
fn main() {
@ -326,8 +317,7 @@ impl<O, T: ?Sized> OwningRef<O, T> {
///
/// # Example
/// ```
/// extern crate owning_ref;
/// use owning_ref::OwningRef;
/// use rustc_data_structures::owning_ref::OwningRef;
///
/// fn main() {
/// let owning_ref = OwningRef::new(Box::new(42));
@ -362,8 +352,7 @@ impl<O, T: ?Sized> OwningRef<O, T> {
///
/// # Example
/// ```
/// extern crate owning_ref;
/// use owning_ref::OwningRef;
/// use rustc_data_structures::owning_ref::OwningRef;
///
/// fn main() {
/// let owning_ref = OwningRef::new(Box::new([1, 2, 3, 4]));
@ -390,8 +379,7 @@ impl<O, T: ?Sized> OwningRef<O, T> {
///
/// # Example
/// ```
/// extern crate owning_ref;
/// use owning_ref::OwningRef;
/// use rustc_data_structures::owning_ref::OwningRef;
///
/// fn main() {
/// let owning_ref = OwningRef::new(Box::new([1, 2, 3, 4]));
@ -441,8 +429,7 @@ impl<O, T: ?Sized> OwningRef<O, T> {
///
/// # Example
/// ```
/// extern crate owning_ref;
/// use owning_ref::{OwningRef, Erased};
/// use rustc_data_structures::owning_ref::{OwningRef, Erased};
///
/// fn main() {
/// // N.B., using the concrete types here for explicitness.
@ -460,7 +447,7 @@ impl<O, T: ?Sized> OwningRef<O, T> {
/// let owning_ref_b: OwningRef<Box<Vec<(i32, bool)>>, i32>
/// = owning_ref_b.map(|a| &a[1].0);
///
/// let owning_refs: [OwningRef<Box<Erased>, i32>; 2]
/// let owning_refs: [OwningRef<Box<dyn Erased>, i32>; 2]
/// = [owning_ref_a.erase_owner(), owning_ref_b.erase_owner()];
///
/// assert_eq!(*owning_refs[0], 1);
@ -516,8 +503,7 @@ impl<O, T: ?Sized> OwningRefMut<O, T> {
///
/// # Example
/// ```
/// extern crate owning_ref;
/// use owning_ref::OwningRefMut;
/// use rustc_data_structures::owning_ref::OwningRefMut;
///
/// fn main() {
/// let owning_ref_mut = OwningRefMut::new(Box::new(42));
@ -552,8 +538,7 @@ impl<O, T: ?Sized> OwningRefMut<O, T> {
///
/// # Example
/// ```
/// extern crate owning_ref;
/// use owning_ref::OwningRefMut;
/// use rustc_data_structures::owning_ref::OwningRefMut;
///
/// fn main() {
/// let owning_ref_mut = OwningRefMut::new(Box::new([1, 2, 3, 4]));
@ -580,8 +565,7 @@ impl<O, T: ?Sized> OwningRefMut<O, T> {
///
/// # Example
/// ```
/// extern crate owning_ref;
/// use owning_ref::OwningRefMut;
/// use rustc_data_structures::owning_ref::OwningRefMut;
///
/// fn main() {
/// let owning_ref_mut = OwningRefMut::new(Box::new([1, 2, 3, 4]));
@ -608,8 +592,7 @@ impl<O, T: ?Sized> OwningRefMut<O, T> {
///
/// # Example
/// ```
/// extern crate owning_ref;
/// use owning_ref::OwningRefMut;
/// use rustc_data_structures::owning_ref::OwningRefMut;
///
/// fn main() {
/// let owning_ref_mut = OwningRefMut::new(Box::new([1, 2, 3, 4]));
@ -638,8 +621,7 @@ impl<O, T: ?Sized> OwningRefMut<O, T> {
///
/// # Example
/// ```
/// extern crate owning_ref;
/// use owning_ref::OwningRefMut;
/// use rustc_data_structures::owning_ref::OwningRefMut;
///
/// fn main() {
/// let owning_ref_mut = OwningRefMut::new(Box::new([1, 2, 3, 4]));
@ -689,8 +671,7 @@ impl<O, T: ?Sized> OwningRefMut<O, T> {
///
/// # Example
/// ```
/// extern crate owning_ref;
/// use owning_ref::{OwningRefMut, Erased};
/// use rustc_data_structures::owning_ref::{OwningRefMut, Erased};
///
/// fn main() {
/// // N.B., using the concrete types here for explicitness.
@ -708,7 +689,7 @@ impl<O, T: ?Sized> OwningRefMut<O, T> {
/// let owning_ref_mut_b: OwningRefMut<Box<Vec<(i32, bool)>>, i32>
/// = owning_ref_mut_b.map_mut(|a| &mut a[1].0);
///
/// let owning_refs_mut: [OwningRefMut<Box<Erased>, i32>; 2]
/// let owning_refs_mut: [OwningRefMut<Box<dyn Erased>, i32>; 2]
/// = [owning_ref_mut_a.erase_owner(), owning_ref_mut_b.erase_owner()];
///
/// assert_eq!(*owning_refs_mut[0], 1);

View file

@ -45,7 +45,8 @@ pub unsafe trait Pointer: Deref {
/// case you'll need to manually figure out what the right type to pass to
/// align_of is.
///
/// ```rust
/// ```ignore UNSOLVED (what to do about the Self)
/// # use std::ops::Deref;
/// std::mem::align_of::<<Self as Deref>::Target>().trailing_zeros() as usize;
/// ```
const BITS: usize;

View file

@ -282,7 +282,7 @@ impl<T: Eq + Hash + Copy> TransitiveRelation<T> {
/// (where the relation is encoding the `<=` relation for the lattice).
/// So e.g., if the relation is `->` and we have
///
/// ```
/// ```text
/// a -> b -> d -> f
/// | ^
/// +--> c -> e ---+

View file

@ -100,7 +100,7 @@ pub struct CodeSuggestion {
/// `foo.bar` might be replaced with `a.b` or `x.y` by replacing
/// `foo` and `bar` on their own:
///
/// ```
/// ```ignore (illustrative)
/// vec![
/// Substitution { parts: vec![(0..3, "a"), (4..7, "b")] },
/// Substitution { parts: vec![(0..3, "x"), (4..7, "y")] },
@ -109,7 +109,7 @@ pub struct CodeSuggestion {
///
/// or by replacing the entire span:
///
/// ```
/// ```ignore (illustrative)
/// vec![
/// Substitution { parts: vec![(0..7, "a.b")] },
/// Substitution { parts: vec![(0..7, "x.y")] },

View file

@ -4,7 +4,7 @@
//!
//! ## Meta-variables must not be bound twice
//!
//! ```
//! ```compile_fail
//! macro_rules! foo { ($x:tt $x:tt) => { $x }; }
//! ```
//!
@ -604,9 +604,9 @@ fn check_ops_is_prefix(
/// Kleene operators of its binder as a prefix.
///
/// Consider $i in the following example:
///
/// ( $( $i:ident = $($j:ident),+ );* ) => { $($( $i += $j; )+)* }
///
/// ```ignore (illustrative)
/// ( $( $i:ident = $($j:ident),+ );* ) => { $($( $i += $j; )+)* }
/// ```
/// It occurs under the Kleene stack ["*", "+"] and is bound under ["*"] only.
///
/// Arguments:

View file

@ -320,7 +320,8 @@ pub(super) fn count_metavar_decls(matcher: &[TokenTree]) -> usize {
///
/// Then, the tree will have the following shape:
///
/// ```rust
/// ```ignore (private-internal)
/// # use NamedMatch::*;
/// MatchedSeq([
/// MatchedSeq([
/// MatchedNonterminal(a),

View file

@ -312,6 +312,7 @@ pub enum Res<Id = hir::HirId> {
/// HACK(min_const_generics): self types also have an optional requirement to **not** mention
/// any generic parameters to allow the following with `min_const_generics`:
/// ```
/// # struct Foo;
/// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] { todo!() } }
///
/// struct Bar([u8; baz::<Self>()]);

View file

@ -49,15 +49,15 @@ pub enum ParamName {
/// Synthetic name generated when user elided a lifetime in an impl header.
///
/// E.g., the lifetimes in cases like these:
///
/// impl Foo for &u32
/// impl Foo<'_> for u32
///
/// ```ignore (fragment)
/// impl Foo for &u32
/// impl Foo<'_> for u32
/// ```
/// in that case, we rewrite to
///
/// impl<'f> Foo for &'f u32
/// impl<'f> Foo<'f> for u32
///
/// ```ignore (fragment)
/// impl<'f> Foo for &'f u32
/// impl<'f> Foo<'f> for u32
/// ```
/// where `'f` is something like `Fresh(0)`. The indices are
/// unique per impl, but not necessarily continuous.
Fresh(LocalDefId),
@ -1082,7 +1082,7 @@ pub enum PatKind<'hir> {
/// If `slice` exists, then `after` can be non-empty.
///
/// The representation for e.g., `[a, b, .., c, d]` is:
/// ```
/// ```ignore (illustrative)
/// PatKind::Slice([Binding(a), Binding(b)], Some(Wild), [Binding(c), Binding(d)])
/// ```
Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]),
@ -2247,7 +2247,7 @@ pub const FN_OUTPUT_NAME: Symbol = sym::Output;
/// wouldn't it be better to make the `ty` field an enum like the
/// following?
///
/// ```
/// ```ignore (pseudo-rust)
/// enum TypeBindingKind {
/// Equals(...),
/// Binding(...),

View file

@ -22,7 +22,7 @@
//!
//! Example:
//!
//! ```
//! ```ignore (needs flags)
//! #[rustc_if_this_changed(Hir)]
//! fn foo() { }
//!

View file

@ -5,6 +5,7 @@
//! The user adds annotations to the crate of the following form:
//!
//! ```
//! # #![feature(rustc_attrs)]
//! #![rustc_partition_reused(module="spike", cfg="rpass2")]
//! #![rustc_partition_codegened(module="spike-x", cfg="rpass2")]
//! ```

View file

@ -6,7 +6,7 @@
//! is always the "expected" output from the POV of diagnostics.
//!
//! Examples:
//!
//! ```ignore (fragment)
//! infcx.at(cause, param_env).sub(a, b)
//! // requires that `a <: b`, with `a` considered the "expected" type
//!
@ -15,11 +15,11 @@
//!
//! infcx.at(cause, param_env).eq(a, b)
//! // requires that `a == b`, with `a` considered the "expected" type
//!
//! ```
//! For finer-grained control, you can also do use `trace`:
//!
//! ```ignore (fragment)
//! infcx.at(...).trace(a, b).sub(&c, &d)
//!
//! ```
//! This will set `a` and `b` as the "root" values for
//! error-reporting, but actually operate on `c` and `d`. This is
//! sometimes useful when the types of `c` and `d` are not traceable

View file

@ -87,9 +87,9 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
///
/// with a mapping M that maps `'?0` to `'static`. But if we found that there
/// exists only one possible impl of `Trait`, and it looks like
///
/// impl<T> Trait<'static> for T { .. }
///
/// ```ignore (illustrative)
/// impl<T> Trait<'static> for T { .. }
/// ```
/// then we would prepare a query result R that (among other
/// things) includes a mapping to `'?0 := 'static`. When
/// canonicalizing this query result R, we would leave this

View file

@ -202,7 +202,7 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
///
/// A good example of this is the following:
///
/// ```rust
/// ```compile_fail,E0308
/// #![feature(generic_const_exprs)]
///
/// fn bind<const N: usize>(value: [u8; N]) -> [u8; 3 + 4] {

View file

@ -889,7 +889,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
///
/// For the following code:
///
/// ```no_run
/// ```ignore (illustrative)
/// let x: Foo<Bar<Qux>> = foo::<Bar<Qux>>();
/// ```
///
@ -1872,7 +1872,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
/// A possible error is to forget to add `.await` when using futures:
///
/// ```
/// ```compile_fail,E0308
/// async fn make_u32() -> u32 {
/// 22
/// }

View file

@ -18,7 +18,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
///
/// Consider a case where we have
///
/// ```no_run
/// ```compile_fail,E0623
/// fn foo(x: &mut Vec<&u8>, y: &u8) {
/// x.push(y);
/// }

View file

@ -14,7 +14,7 @@ use rustc_middle::ty::{self, Region, TyCtxt};
/// br - the bound region corresponding to the above region which is of type `BrAnon(_)`
///
/// # Example
/// ```
/// ```compile_fail,E0623
/// fn foo(x: &mut Vec<&u8>, y: &u8)
/// { x.push(y); }
/// ```

View file

@ -159,9 +159,9 @@ pub struct InferCtxtInner<'tcx> {
/// outlive the lifetime 'a". These constraints derive from
/// instantiated type parameters. So if you had a struct defined
/// like
///
/// ```ignore (illustrative)
/// struct Foo<T:'static> { ... }
///
/// ```
/// then in some expression `let x = Foo { ... }` it will
/// instantiate the type parameter `T` with a fresh type `$0`. At
/// the same time, it will record a region obligation of

View file

@ -309,14 +309,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
/// the same as generating an outlives constraint on `Tc` itself.
/// For example, if we had a function like this:
///
/// ```rust
/// ```
/// # #![feature(type_alias_impl_trait)]
/// # fn main() {}
/// # trait Foo<'a> {}
/// # impl<'a, T> Foo<'a> for (&'a u32, T) {}
/// fn foo<'a, T>(x: &'a u32, y: T) -> impl Foo<'a> {
/// (x, y)
/// }
///
/// // Equivalent to:
/// # mod dummy { use super::*;
/// type FooReturn<'a, T> = impl Foo<'a>;
/// fn foo<'a, T>(..) -> FooReturn<'a, T> { .. }
/// fn foo<'a, T>(x: &'a u32, y: T) -> FooReturn<'a, T> {
/// (x, y)
/// }
/// # }
/// ```
///
/// then the hidden type `Tc` would be `(&'0 u32, T)` (where `'0`
@ -602,17 +610,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
/// Returns `true` if `opaque_hir_id` is a sibling or a child of a sibling of `def_id`.
///
/// Example:
/// ```rust
/// ```ignore UNSOLVED (is this a bug?)
/// # #![feature(type_alias_impl_trait)]
/// pub mod foo {
/// pub mod bar {
/// pub trait Bar { .. }
///
/// pub trait Bar { /* ... */ }
/// pub type Baz = impl Bar;
///
/// fn f1() -> Baz { .. }
/// # impl Bar for () {}
/// fn f1() -> Baz { /* ... */ }
/// }
///
/// fn f2() -> bar::Baz { .. }
/// fn f2() -> bar::Baz { /* ... */ }
/// }
/// ```
///

View file

@ -103,7 +103,7 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
///
/// Example:
///
/// ```
/// ```ignore (pseudo-rust)
/// fn foo<T>() {
/// callback(for<'a> |x: &'a T| {
/// // ^^^^^^^ not legal syntax, but probably should be

View file

@ -33,9 +33,9 @@
//! Consider:
//!
//! ```
//! fn bar<T>(a: T, b: impl for<'a> Fn(&'a T));
//! fn bar<T>(a: T, b: impl for<'a> Fn(&'a T)) {}
//! fn foo<T>(x: T) {
//! bar(x, |y| { ... })
//! bar(x, |y| { /* ... */})
//! // ^ closure arg
//! }
//! ```

View file

@ -313,7 +313,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
///
/// It will not, however, work for higher-ranked bounds like:
///
/// ```rust
/// ```compile_fail,E0311
/// trait Foo<'a, 'b>
/// where for<'x> <Self as Foo<'x, 'b>>::Bar: 'x
/// {

View file

@ -174,19 +174,19 @@ pub enum GenericKind<'tcx> {
/// Describes the things that some `GenericKind` value `G` is known to
/// outlive. Each variant of `VerifyBound` can be thought of as a
/// function:
///
/// fn(min: Region) -> bool { .. }
///
/// ```ignore (pseudo-rust)
/// fn(min: Region) -> bool { .. }
/// ```
/// where `true` means that the region `min` meets that `G: min`.
/// (False means nothing.)
///
/// So, for example, if we have the type `T` and we have in scope that
/// `T: 'a` and `T: 'b`, then the verify bound might be:
///
/// fn(min: Region) -> bool {
/// ('a: min) || ('b: min)
/// }
///
/// ```ignore (pseudo-rust)
/// fn(min: Region) -> bool {
/// ('a: min) || ('b: min)
/// }
/// ```
/// This is described with an `AnyRegion('a, 'b)` node.
#[derive(Debug, Clone)]
pub enum VerifyBound<'tcx> {
@ -194,7 +194,7 @@ pub enum VerifyBound<'tcx> {
/// following, where `G` is the generic for which this verify
/// bound was created:
///
/// ```rust
/// ```ignore (pseudo-rust)
/// fn(min) -> bool {
/// if G == K {
/// B(min)
@ -218,7 +218,7 @@ pub enum VerifyBound<'tcx> {
///
/// So we would compile to a verify-bound like
///
/// ```
/// ```ignore (illustrative)
/// IfEq(<T as Trait<'a>>::Item, AnyRegion('a))
/// ```
///
@ -228,7 +228,7 @@ pub enum VerifyBound<'tcx> {
/// Given a region `R`, expands to the function:
///
/// ```
/// ```ignore (pseudo-rust)
/// fn(min) -> bool {
/// R: min
/// }
@ -243,7 +243,7 @@ pub enum VerifyBound<'tcx> {
/// Given a set of bounds `B`, expands to the function:
///
/// ```rust
/// ```ignore (pseudo-rust)
/// fn(min) -> bool {
/// exists (b in B) { b(min) }
/// }
@ -255,7 +255,7 @@ pub enum VerifyBound<'tcx> {
/// Given a set of bounds `B`, expands to the function:
///
/// ```rust
/// ```ignore (pseudo-rust)
/// fn(min) -> bool {
/// forall (b in B) { b(min) }
/// }

View file

@ -73,10 +73,10 @@ pub struct TypeVariableStorage<'tcx> {
/// table exists only to help with the occurs check. In particular,
/// we want to report constraints like these as an occurs check
/// violation:
///
/// ?1 <: ?3
/// Box<?3> <: ?1
///
/// ``` text
/// ?1 <: ?3
/// Box<?3> <: ?1
/// ```
/// Without this second table, what would happen in a case like
/// this is that we would instantiate `?1` with a generalized
/// type like `Box<?6>`. We would then relate `Box<?3> <: Box<?6>`
@ -287,8 +287,9 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
/// related via equality or subtyping will yield the same root
/// variable (per the union-find algorithm), so `sub_root_var(a)
/// == sub_root_var(b)` implies that:
///
/// exists X. (a <: X || X <: a) && (b <: X || X <: b)
/// ```text
/// exists X. (a <: X || X <: a) && (b <: X || X <: b)
/// ```
pub fn sub_root_var(&mut self, vid: ty::TyVid) -> ty::TyVid {
self.sub_relations().find(vid)
}

View file

@ -1109,7 +1109,8 @@ declare_lint! {
///
/// ### Example
///
/// ```rust,compile_fail
/// ```compile_fail
/// #![deny(unaligned_references)]
/// #[repr(packed)]
/// pub struct Foo {
/// field1: u64,

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>

View file

@ -42,15 +42,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// We tweak the handling of parameters of unsized type slightly to avoid the need to create a
/// local variable of unsized type. For example, consider this program:
///
/// ```rust
/// fn foo(p: dyn Debug) { ... }
/// ```
/// #![feature(unsized_locals, unsized_fn_params)]
/// # use core::fmt::Debug;
/// fn foo(p: dyn Debug) { dbg!(p); }
///
/// fn bar(box_p: Box<dyn Debug>) { foo(*p); }
/// fn bar(box_p: Box<dyn Debug>) { foo(*box_p); }
/// ```
///
/// Ordinarily, for sized types, we would compile the call `foo(*p)` like so:
///
/// ```rust
/// ```ignore (illustrative)
/// let tmp0 = *box_p; // tmp0 would be the operand returned by this function call
/// foo(tmp0)
/// ```
@ -60,7 +62,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// that we create *stores the entire box*, and the parameter to the call itself will be
/// `*tmp0`:
///
/// ```rust
/// ```ignore (illustrative)
/// let tmp0 = box_p; call foo(*tmp0)
/// ```
///

View file

@ -37,7 +37,7 @@ crate enum PlaceBase {
///
/// Consider the following example
/// ```rust
/// let t = (10, (10, (10, 10)));
/// let t = (((10, 10), 10), 10);
///
/// let c = || {
/// println!("{}", t.0.0.0);
@ -45,7 +45,7 @@ crate enum PlaceBase {
/// ```
/// Here the THIR expression for `t.0.0.0` will be something like
///
/// ```
/// ```ignore (illustrative)
/// * Field(0)
/// * Field(0)
/// * Field(0)

View file

@ -1032,11 +1032,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// exhaustive match, consider:
///
/// ```
/// # fn foo(x: (bool, bool)) {
/// match x {
/// (true, true) => (),
/// (_, false) => (),
/// (false, true) => (),
/// }
/// # }
/// ```
///
/// For this match, we check if `x.0` matches `true` (for the first
@ -1157,7 +1159,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
///
/// For example, if we have something like this:
///
/// ```rust
/// ```ignore (illustrative)
/// ...
/// Some(x) if cond1 => ...
/// Some(x) => ...
@ -1481,11 +1483,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// ```
/// # let (x, y, z) = (true, true, true);
/// match (x, y, z) {
/// (true, _, true) => true, // (0)
/// (_, true, _) => true, // (1)
/// (false, false, _) => false, // (2)
/// (true, _, false) => false, // (3)
/// (true , _ , true ) => true, // (0)
/// (_ , true , _ ) => true, // (1)
/// (false, false, _ ) => false, // (2)
/// (true , _ , false) => false, // (3)
/// }
/// # ;
/// ```
///
/// In that case, after we test on `x`, there are 2 overlapping candidate
@ -1502,14 +1505,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// with precisely the reachable arms being reachable - but that problem
/// is trivially NP-complete:
///
/// ```rust
/// match (var0, var1, var2, var3, ...) {
/// (true, _, _, false, true, ...) => false,
/// (_, true, true, false, _, ...) => false,
/// (false, _, false, false, _, ...) => false,
/// ...
/// _ => true
/// }
/// ```ignore (illustrative)
/// match (var0, var1, var2, var3, ...) {
/// (true , _ , _ , false, true, ...) => false,
/// (_ , true, true , false, _ , ...) => false,
/// (false, _ , false, false, _ , ...) => false,
/// ...
/// _ => true
/// }
/// ```
///
/// Here the last arm is reachable only if there is an assignment to
@ -1520,7 +1523,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// our simplistic treatment of constants and guards would make it occur
/// in very common situations - for example [#29740]:
///
/// ```rust
/// ```ignore (illustrative)
/// match x {
/// "foo" if foo_guard => ...,
/// "bar" if bar_guard => ...,

View file

@ -803,16 +803,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// scope (which can be larger or smaller).
///
/// Consider:
///
/// let x = foo(bar(X, Y));
///
/// ```ignore (illustrative)
/// let x = foo(bar(X, Y));
/// ```
/// We wish to pop the storage for X and Y after `bar()` is
/// called, not after the whole `let` is completed.
///
/// As another example, if the second argument diverges:
///
/// foo(Box::new(2), panic!())
///
/// ```ignore (illustrative)
/// foo(Box::new(2), panic!())
/// ```
/// We would allocate the box but then free it on the unwinding
/// path; we would also emit a free on the 'success' path from
/// panic, but that will turn out to be removed as dead-code.
@ -944,7 +944,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
///
/// Example: when compiling the call to `foo` here:
///
/// ```rust
/// ```ignore (illustrative)
/// foo(bar(), ...)
/// ```
///
@ -955,7 +955,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// dropped). However, if no unwind occurs, then `_X` will be
/// unconditionally consumed by the `call`:
///
/// ```
/// ```ignore (illustrative)
/// bb {
/// ...
/// _R = CALL(foo, _X, ...)

View file

@ -13,7 +13,7 @@
//! Instead of listing all those constructors (which is intractable), we group those value
//! constructors together as much as possible. Example:
//!
//! ```
//! ```compile_fail,E0004
//! match (0, false) {
//! (0 ..=100, true) => {} // `p_1`
//! (50..=150, false) => {} // `p_2`
@ -344,13 +344,13 @@ enum IntBorder {
/// straddles the boundary of one of the inputs.
///
/// The following input:
/// ```
/// ```text
/// |-------------------------| // `self`
/// |------| |----------| |----|
/// |-------| |-------|
/// ```
/// would be iterated over as follows:
/// ```
/// ```text
/// ||---|--||-|---|---|---|--|
/// ```
#[derive(Debug, Clone)]
@ -492,14 +492,17 @@ impl Slice {
///
/// Let's look at an example, where we are trying to split the last pattern:
/// ```
/// # fn foo(x: &[bool]) {
/// match x {
/// [true, true, ..] => {}
/// [.., false, false] => {}
/// [..] => {}
/// }
/// # }
/// ```
/// Here are the results of specialization for the first few lengths:
/// ```
/// # fn foo(x: &[bool]) { match x {
/// // length 0
/// [] => {}
/// // length 1
@ -520,6 +523,8 @@ impl Slice {
/// [true, true, _, _, _ ] => {}
/// [_, _, _, false, false] => {}
/// [_, _, _, _, _ ] => {}
/// # _ => {}
/// # }}
/// ```
///
/// If we went above length 5, we would simply be inserting more columns full of wildcards in the
@ -1128,7 +1133,8 @@ impl<'tcx> SplitWildcard<'tcx> {
/// In the following example `Fields::wildcards` returns `[_, _, _, _]`. Then in
/// `extract_pattern_arguments` we fill some of the entries, and the result is
/// `[Some(0), _, _, _]`.
/// ```rust
/// ```compile_fail,E0004
/// # fn foo() -> [Option<u8>; 4] { [None; 4] }
/// let x: [Option<u8>; 4] = foo();
/// match x {
/// [Some(0), ..] => {}

View file

@ -35,23 +35,27 @@
//! This is enough to compute reachability: a pattern in a `match` expression is reachable iff it
//! is useful w.r.t. the patterns above it:
//! ```rust
//! # fn foo(x: Option<i32>) {
//! match x {
//! Some(_) => ...,
//! None => ..., // reachable: `None` is matched by this but not the branch above
//! Some(0) => ..., // unreachable: all the values this matches are already matched by
//! // `Some(_)` above
//! Some(_) => {},
//! None => {}, // reachable: `None` is matched by this but not the branch above
//! Some(0) => {}, // unreachable: all the values this matches are already matched by
//! // `Some(_)` above
//! }
//! # }
//! ```
//!
//! This is also enough to compute exhaustiveness: a match is exhaustive iff the wildcard `_`
//! pattern is _not_ useful w.r.t. the patterns in the match. The values returned by `usefulness`
//! are used to tell the user which values are missing.
//! ```rust
//! ```compile_fail,E0004
//! # fn foo(x: Option<i32>) {
//! match x {
//! Some(0) => ...,
//! None => ...,
//! Some(0) => {},
//! None => {},
//! // not exhaustive: `_` is useful because it matches `Some(1)`
//! }
//! # }
//! ```
//!
//! The entrypoint of this file is the [`compute_match_usefulness`] function, which computes
@ -120,12 +124,15 @@
//! say from knowing only the first constructor of our candidate value.
//!
//! Let's take the following example:
//! ```
//! ```compile_fail,E0004
//! # enum Enum { Variant1(()), Variant2(Option<bool>, u32)}
//! # fn foo(x: Enum) {
//! match x {
//! Enum::Variant1(_) => {} // `p1`
//! Enum::Variant2(None, 0) => {} // `p2`
//! Enum::Variant2(Some(_), 0) => {} // `q`
//! }
//! # }
//! ```
//!
//! We can easily see that if our candidate value `v` starts with `Variant1` it will not match `q`.
@ -133,11 +140,13 @@
//! and `v1`. In fact, such a `v` will be a witness of usefulness of `q` exactly when the tuple
//! `(v0, v1)` is a witness of usefulness of `q'` in the following reduced match:
//!
//! ```
//! ```compile_fail,E0004
//! # fn foo(x: (Option<bool>, u32)) {
//! match x {
//! (None, 0) => {} // `p2'`
//! (Some(_), 0) => {} // `q'`
//! }
//! # }
//! ```
//!
//! This motivates a new step in computing usefulness, that we call _specialization_.
@ -150,7 +159,7 @@
//! like a stack. We note a pattern-stack simply with `[p_1 ... p_n]`.
//! Here's a sequence of specializations of a list of pattern-stacks, to illustrate what's
//! happening:
//! ```
//! ```ignore (illustrative)
//! [Enum::Variant1(_)]
//! [Enum::Variant2(None, 0)]
//! [Enum::Variant2(Some(_), 0)]
@ -234,7 +243,7 @@
//! - We return the concatenation of all the witnesses found, if any.
//!
//! Example:
//! ```
//! ```ignore (illustrative)
//! [Some(true)] // p_1
//! [None] // p_2
//! [Some(_)] // q
@ -659,13 +668,15 @@ enum ArmType {
///
/// For example, if we are constructing a witness for the match against
///
/// ```
/// ```compile_fail,E0004
/// # #![feature(type_ascription)]
/// struct Pair(Option<(u32, u32)>, bool);
///
/// # fn foo(p: Pair) {
/// match (p: Pair) {
/// Pair(None, _) => {}
/// Pair(_, false) => {}
/// }
/// # }
/// ```
///
/// We'll perform the following steps:

View file

@ -37,21 +37,21 @@ pub use self::storage_liveness::{MaybeRequiresStorage, MaybeStorageLive};
///
/// ```rust
/// struct S;
/// fn foo(pred: bool) { // maybe-init:
/// // {}
/// let a = S; let b = S; let c; let d; // {a, b}
/// fn foo(pred: bool) { // maybe-init:
/// // {}
/// let a = S; let mut b = S; let c; let d; // {a, b}
///
/// if pred {
/// drop(a); // { b}
/// b = S; // { b}
/// drop(a); // { b}
/// b = S; // { b}
///
/// } else {
/// drop(b); // {a}
/// d = S; // {a, d}
/// drop(b); // {a}
/// d = S; // {a, d}
///
/// } // {a, b, d}
/// } // {a, b, d}
///
/// c = S; // {a, b, c, d}
/// c = S; // {a, b, c, d}
/// }
/// ```
///
@ -90,21 +90,21 @@ impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> {
///
/// ```rust
/// struct S;
/// fn foo(pred: bool) { // maybe-uninit:
/// // {a, b, c, d}
/// let a = S; let b = S; let c; let d; // { c, d}
/// fn foo(pred: bool) { // maybe-uninit:
/// // {a, b, c, d}
/// let a = S; let mut b = S; let c; let d; // { c, d}
///
/// if pred {
/// drop(a); // {a, c, d}
/// b = S; // {a, c, d}
/// drop(a); // {a, c, d}
/// b = S; // {a, c, d}
///
/// } else {
/// drop(b); // { b, c, d}
/// d = S; // { b, c }
/// drop(b); // { b, c, d}
/// d = S; // { b, c }
///
/// } // {a, b, c, d}
/// } // {a, b, c, d}
///
/// c = S; // {a, b, d}
/// c = S; // {a, b, d}
/// }
/// ```
///
@ -155,21 +155,21 @@ impl<'a, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, 'tcx> {
///
/// ```rust
/// struct S;
/// fn foo(pred: bool) { // definite-init:
/// // { }
/// let a = S; let b = S; let c; let d; // {a, b }
/// fn foo(pred: bool) { // definite-init:
/// // { }
/// let a = S; let mut b = S; let c; let d; // {a, b }
///
/// if pred {
/// drop(a); // { b, }
/// b = S; // { b, }
/// drop(a); // { b, }
/// b = S; // { b, }
///
/// } else {
/// drop(b); // {a, }
/// d = S; // {a, d}
/// drop(b); // {a, }
/// d = S; // {a, d}
///
/// } // { }
/// } // { }
///
/// c = S; // { c }
/// c = S; // { c }
/// }
/// ```
///
@ -210,21 +210,21 @@ impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
///
/// ```rust
/// struct S;
/// fn foo(pred: bool) { // ever-init:
/// // { }
/// let a = S; let b = S; let c; let d; // {a, b }
/// fn foo(pred: bool) { // ever-init:
/// // { }
/// let a = S; let mut b = S; let c; let d; // {a, b }
///
/// if pred {
/// drop(a); // {a, b, }
/// b = S; // {a, b, }
/// drop(a); // {a, b, }
/// b = S; // {a, b, }
///
/// } else {
/// drop(b); // {a, b, }
/// d = S; // {a, b, d }
/// drop(b); // {a, b, }
/// d = S; // {a, b, d }
///
/// } // {a, b, d }
/// } // {a, b, d }
///
/// c = S; // {a, b, c, d }
/// c = S; // {a, b, c, d }
/// }
/// ```
pub struct EverInitializedPlaces<'a, 'tcx> {

View file

@ -18,13 +18,13 @@
//! First upvars are stored
//! It is followed by the generator state field.
//! Then finally the MIR locals which are live across a suspension point are stored.
//!
//! ```ignore (illustrative)
//! struct Generator {
//! upvars...,
//! state: u32,
//! mir_locals...,
//! }
//!
//! ```
//! This pass computes the meaning of the state field and the MIR locals which are live
//! across a suspension point. There are however three hardcoded generator states:
//! 0 - Generator have not been resumed yet

View file

@ -14,7 +14,7 @@ pub struct MatchBranchSimplification;
///
/// For example:
///
/// ```rust
/// ```ignore (MIR)
/// bb0: {
/// switchInt(move _3) -> [42_isize: bb1, otherwise: bb2];
/// }
@ -32,7 +32,7 @@ pub struct MatchBranchSimplification;
///
/// into:
///
/// ```rust
/// ```ignore (MIR)
/// bb0: {
/// _2 = Eq(move _3, const 42_isize);
/// goto -> bb3;

View file

@ -12,7 +12,7 @@ use rustc_middle::{
/// Pass to convert `if` conditions on integrals into switches on the integral.
/// For an example, it turns something like
///
/// ```
/// ```ignore (MIR)
/// _3 = Eq(move _4, const 43i32);
/// StorageDead(_4);
/// switchInt(_3) -> [false: bb2, otherwise: bb3];
@ -20,7 +20,7 @@ use rustc_middle::{
///
/// into:
///
/// ```
/// ```ignore (MIR)
/// switchInt(_4) -> [43i32: bb3, otherwise: bb2];
/// ```
pub struct SimplifyComparisonIntegral;

View file

@ -1,10 +1,12 @@
//! The general point of the optimizations provided here is to simplify something like:
//!
//! ```rust
//! # fn foo<T, E>(x: Result<T, E>) -> Result<T, E> {
//! match x {
//! Ok(x) => Ok(x),
//! Err(x) => Err(x)
//! }
//! # }
//! ```
//!
//! into just `x`.
@ -23,7 +25,7 @@ use std::slice::Iter;
///
/// This is done by transforming basic blocks where the statements match:
///
/// ```rust
/// ```ignore (MIR)
/// _LOCAL_TMP = ((_LOCAL_1 as Variant ).FIELD: TY );
/// _TMP_2 = _LOCAL_TMP;
/// ((_LOCAL_0 as Variant).FIELD: TY) = move _TMP_2;
@ -32,7 +34,7 @@ use std::slice::Iter;
///
/// into:
///
/// ```rust
/// ```ignore (MIR)
/// _LOCAL_0 = move _LOCAL_1
/// ```
pub struct SimplifyArmIdentity;
@ -472,7 +474,7 @@ impl Visitor<'_> for LocalUseCounter {
}
/// Match on:
/// ```rust
/// ```ignore (MIR)
/// _LOCAL_INTO = ((_LOCAL_FROM as Variant).FIELD: TY);
/// ```
fn match_get_variant_field<'tcx>(
@ -492,7 +494,7 @@ fn match_get_variant_field<'tcx>(
}
/// Match on:
/// ```rust
/// ```ignore (MIR)
/// ((_LOCAL_FROM as Variant).FIELD: TY) = move _LOCAL_INTO;
/// ```
fn match_set_variant_field<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, Local, VarField<'tcx>)> {
@ -507,7 +509,7 @@ fn match_set_variant_field<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, Local
}
/// Match on:
/// ```rust
/// ```ignore (MIR)
/// discriminant(_LOCAL_TO_SET) = VAR_IDX;
/// ```
fn match_set_discr(stmt: &Statement<'_>) -> Option<(Local, VariantIdx)> {
@ -690,7 +692,7 @@ impl<'tcx> SimplifyBranchSameOptimizationFinder<'_, 'tcx> {
///
/// Statements can be trivially equal if the kinds match.
/// But they can also be considered equal in the following case A:
/// ```
/// ```ignore (MIR)
/// discriminant(_0) = 0; // bb1
/// _0 = move _1; // bb2
/// ```

View file

@ -91,12 +91,13 @@
//! another function. It suffices to just take a reference in order to introduce
//! an edge. Consider the following example:
//!
//! ```rust
//! ```
//! # use core::fmt::Display;
//! fn print_val<T: Display>(x: T) {
//! println!("{}", x);
//! }
//!
//! fn call_fn(f: &Fn(i32), x: i32) {
//! fn call_fn(f: &dyn Fn(i32), x: i32) {
//! f(x);
//! }
//!

View file

@ -371,9 +371,10 @@ impl<'a> Parser<'a> {
}
/// Matches the following grammar (per RFC 1559).
///
/// meta_item : PATH ( '=' UNSUFFIXED_LIT | '(' meta_item_inner? ')' )? ;
/// meta_item_inner : (meta_item | UNSUFFIXED_LIT) (',' meta_item_inner)? ;
/// ```ebnf
/// meta_item : PATH ( '=' UNSUFFIXED_LIT | '(' meta_item_inner? ')' )? ;
/// meta_item_inner : (meta_item | UNSUFFIXED_LIT) (',' meta_item_inner)? ;
/// ```
pub fn parse_meta_item(&mut self) -> PResult<'a, ast::MetaItem> {
let nt_meta = match self.token.kind {
token::Interpolated(ref nt) => match **nt {

View file

@ -485,7 +485,7 @@ impl<'a> Parser<'a> {
/// Parses an implementation item.
///
/// ```
/// ```ignore (illustrative)
/// impl<'a, T> TYPE { /* impl items */ }
/// impl<'a, T> TRAIT for TYPE { /* impl items */ }
/// impl<'a, T> !TRAIT for TYPE { /* impl items */ }
@ -493,7 +493,7 @@ impl<'a> Parser<'a> {
/// ```
///
/// We actually parse slightly more relaxed grammar for better error reporting and recovery.
/// ```
/// ```ebnf
/// "impl" GENERICS "const"? "!"? TYPE "for"? (TYPE | "..") ("where" PREDICATES)? "{" BODY "}"
/// "impl" GENERICS "const"? "!"? TYPE ("where" PREDICATES)? "{" BODY "}"
/// ```
@ -806,7 +806,7 @@ impl<'a> Parser<'a> {
}
/// Parses a `type` alias with the following grammar:
/// ```
/// ```ebnf
/// TypeAlias = "type" Ident Generics {":" GenericBounds}? {"=" Ty}? ";" ;
/// ```
/// The `"type"` has already been eaten.
@ -930,7 +930,7 @@ impl<'a> Parser<'a> {
///
/// # Examples
///
/// ```
/// ```ignore (illustrative)
/// extern crate foo;
/// extern crate bar as foo;
/// ```
@ -1630,7 +1630,7 @@ impl<'a> Parser<'a> {
/// Parses a declarative macro 2.0 definition.
/// The `macro` keyword has already been parsed.
/// ```
/// ```ebnf
/// MacBody = "{" TOKEN_STREAM "}" ;
/// MacParams = "(" TOKEN_STREAM ")" ;
/// DeclMac = "macro" Ident MacParams? MacBody ;

View file

@ -52,7 +52,7 @@ pub(super) enum RecoverQuestionMark {
/// Signals whether parsing a type should recover `->`.
///
/// More specifically, when parsing a function like:
/// ```rust
/// ```compile_fail
/// fn foo() => u8 { 0 }
/// fn bar(): u8 { 0 }
/// ```
@ -499,12 +499,12 @@ impl<'a> Parser<'a> {
}
/// Parses a function pointer type (`TyKind::BareFn`).
/// ```
/// [unsafe] [extern "ABI"] fn (S) -> T
/// ^~~~~^ ^~~~^ ^~^ ^
/// | | | |
/// | | | Return type
/// Function Style ABI Parameter types
/// ```ignore (illustrative)
/// [unsafe] [extern "ABI"] fn (S) -> T
/// // ^~~~~^ ^~~~^ ^~^ ^
/// // | | | |
/// // | | | Return type
/// // Function Style ABI Parameter types
/// ```
/// We actually parse `FnHeader FnDecl`, but we error on `const` and `async` qualifiers.
fn parse_ty_bare_fn(
@ -707,7 +707,7 @@ impl<'a> Parser<'a> {
}
/// Parses a bound according to the grammar:
/// ```
/// ```ebnf
/// BOUND = TY_BOUND | LT_BOUND
/// ```
fn parse_generic_bound(&mut self) -> PResult<'a, Result<GenericBound, Span>> {
@ -729,7 +729,7 @@ impl<'a> Parser<'a> {
}
/// Parses a lifetime ("outlives") bound, e.g. `'a`, according to:
/// ```
/// ```ebnf
/// LT_BOUND = LIFETIME
/// ```
fn parse_generic_lt_bound(
@ -787,7 +787,7 @@ impl<'a> Parser<'a> {
///
/// If no modifiers are present, this does not consume any tokens.
///
/// ```
/// ```ebnf
/// TY_BOUND_MODIFIERS = ["~const"] ["?"]
/// ```
fn parse_ty_bound_modifiers(&mut self) -> PResult<'a, BoundModifiers> {
@ -807,7 +807,7 @@ impl<'a> Parser<'a> {
}
/// Parses a type bound according to:
/// ```
/// ```ebnf
/// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
/// TY_BOUND_NOPAREN = [TY_BOUND_MODIFIERS] [for<LT_PARAM_DEFS>] SIMPLE_PATH
/// ```

View file

@ -7,9 +7,9 @@ use std::error::Error;
/// A dep-node filter goes from a user-defined string to a query over
/// nodes. Right now the format is like this:
///
/// x & y & z
///
/// ```ignore (illustrative)
/// x & y & z
/// ```
/// where the format-string of the dep-node must contain `x`, `y`, and
/// `z`.
#[derive(Debug)]

View file

@ -2273,16 +2273,16 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
/// Given a `binding_span` of a binding within a use statement:
///
/// ```
/// ```ignore (illustrative)
/// use foo::{a, b, c};
/// ^
/// // ^
/// ```
///
/// then return the span until the next binding or the end of the statement:
///
/// ```
/// ```ignore (illustrative)
/// use foo::{a, b, c};
/// ^^^
/// // ^^^
/// ```
fn find_span_of_binding_until_next_binding(
sess: &Session,
@ -2326,14 +2326,14 @@ fn find_span_of_binding_until_next_binding(
/// Given a `binding_span`, return the span through to the comma or opening brace of the previous
/// binding.
///
/// ```
/// ```ignore (illustrative)
/// use foo::a::{a, b, c};
/// ^^--- binding span
/// |
/// returned span
/// // ^^--- binding span
/// // |
/// // returned span
///
/// use foo::{a, b, c};
/// --- binding span
/// // --- binding span
/// ```
fn extend_span_to_previous_binding(sess: &Session, binding_span: Span) -> Option<Span> {
let source_map = sess.source_map();
@ -2369,15 +2369,15 @@ fn extend_span_to_previous_binding(sess: &Session, binding_span: Span) -> Option
/// Given a `use_span` of a binding within a use statement, returns the highlighted span and if
/// it is a nested use tree.
///
/// ```
/// ```ignore (illustrative)
/// use foo::a::{b, c};
/// ^^^^^^^^^^ // false
/// // ^^^^^^^^^^ -- false
///
/// use foo::{a, b, c};
/// ^^^^^^^^^^ // true
/// // ^^^^^^^^^^ -- true
///
/// use foo::{a, b::{c, d}};
/// ^^^^^^^^^^^^^^^ // true
/// // ^^^^^^^^^^^^^^^ -- true
/// ```
fn find_span_immediately_after_crate_name(
sess: &Session,

View file

@ -401,7 +401,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
/// The reason for this separate call is to resolve what would otherwise
/// be a cycle. Consider this example:
///
/// ```rust
/// ```ignore UNSOLVED (maybe @jackh726 knows what lifetime parameter to give Sub)
/// trait Base<'a> {
/// type BaseItem;
/// }
@ -2552,7 +2552,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
/// Returns all the late-bound vars that come into scope from supertrait HRTBs, based on the
/// associated type name and starting trait.
/// For example, imagine we have
/// ```rust
/// ```ignore (illustrative)
/// trait Foo<'a, 'b> {
/// type As;
/// }

View file

@ -686,7 +686,7 @@ impl SyntaxContext {
/// context up one macro definition level. That is, if we have a nested macro
/// definition as follows:
///
/// ```rust
/// ```ignore (illustrative)
/// macro_rules! f {
/// macro_rules! g {
/// ...
@ -710,6 +710,7 @@ impl SyntaxContext {
/// For example, consider the following three resolutions of `f`:
///
/// ```rust
/// #![feature(decl_macro)]
/// mod foo { pub fn f() {} } // `f`'s `SyntaxContext` is empty.
/// m!(f);
/// macro m($f:ident) {
@ -746,7 +747,8 @@ impl SyntaxContext {
/// via a glob import with the given `SyntaxContext`.
/// For example:
///
/// ```rust
/// ```compile_fail,E0425
/// #![feature(decl_macro)]
/// m!(f);
/// macro m($i:ident) {
/// mod foo {
@ -786,7 +788,7 @@ impl SyntaxContext {
/// Undo `glob_adjust` if possible:
///
/// ```rust
/// ```ignore (illustrative)
/// if let Some(privacy_checking_scope) = self.reverse_glob_adjust(expansion, glob_ctxt) {
/// assert!(self.glob_adjust(expansion, glob_ctxt) == Some(privacy_checking_scope));
/// }

View file

@ -1058,10 +1058,11 @@ impl SourceMap {
/// Tries to find the span of the semicolon of a macro call statement.
/// The input must be the *call site* span of a statement from macro expansion.
///
/// v output
/// mac!();
/// ^^^^^^ input
/// ```ignore (illustrative)
/// // v output
/// mac!();
/// // ^^^^^^ input
/// ```
pub fn mac_call_stmt_semi_span(&self, mac_call: Span) -> Option<Span> {
let span = self.span_extend_while(mac_call, char::is_whitespace).ok()?;
let span = span.shrink_to_hi().with_hi(BytePos(span.hi().0.checked_add(1)?));

View file

@ -22,11 +22,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
/// (*), computes the "definition type" for an opaque type
/// definition -- that is, the inferred value of `Foo1<'x>` or
/// `Foo2<'x>` that we would conceptually use in its definition:
///
/// type Foo1<'x> = impl Bar<'x> = AAA; <-- this type AAA
/// type Foo2<'x> = impl Bar<'x> = BBB; <-- or this type BBB
/// fn foo<'a, 'b>(..) -> (Foo1<'a>, Foo2<'b>) { .. }
///
/// ```ignore (illustrative)
/// type Foo1<'x> = impl Bar<'x> = AAA; // <-- this type AAA
/// type Foo2<'x> = impl Bar<'x> = BBB; // <-- or this type BBB
/// fn foo<'a, 'b>(..) -> (Foo1<'a>, Foo2<'b>) { .. }
/// ```
/// Note that these values are defined in terms of a distinct set of
/// generic parameters (`'x` instead of `'a`) from C1 or C2. The main
/// purpose of this function is to do that translation.

View file

@ -255,9 +255,9 @@ impl<'tcx> AutoTraitFinder<'tcx> {
/// `FulfillmentContext` will drive `SelectionContext` to consider that impl before giving up.
/// If we were to rely on `FulfillmentContext`s decision, we might end up synthesizing an impl
/// like this:
///
/// impl<T> Send for Foo<T> where T: IntoIterator
///
/// ```ignore (illustrative)
/// impl<T> Send for Foo<T> where T: IntoIterator
/// ```
/// While it might be technically true that Foo implements Send where `T: IntoIterator`,
/// the bound is overly restrictive - it's really only necessary that `T: Iterator`.
///
@ -420,10 +420,10 @@ impl<'tcx> AutoTraitFinder<'tcx> {
/// two trait predicates that differ only in their region parameters:
/// one containing a HRTB lifetime parameter, and one containing a 'normal'
/// lifetime parameter. For example:
///
/// T as MyTrait<'a>
/// T as MyTrait<'static>
///
/// ```ignore (illustrative)
/// T as MyTrait<'a>
/// T as MyTrait<'static>
/// ```
/// If we put both of these predicates in our computed `ParamEnv`, we'll
/// confuse `SelectionContext`, since it will (correctly) view both as being applicable.
///

View file

@ -547,7 +547,7 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe
/// 2. They ground negative reasoning for coherence. If a user wants to
/// write both a conditional blanket impl and a specific impl, we need to
/// make sure they do not overlap. For example, if we write
/// ```
/// ```ignore (illustrative)
/// impl<T> IntoIterator for Vec<T>
/// impl<T: Iterator> IntoIterator for T
/// ```

View file

@ -595,7 +595,7 @@ fn object_ty_for_trait<'tcx>(
/// - let `Receiver` be the type of the `self` argument, i.e `Self`, `&Self`, `Rc<Self>`,
/// - require the following bound:
///
/// ```
/// ```ignore (not-rust)
/// Receiver[Self => T]: DispatchFromDyn<Receiver[Self => dyn Trait]>
/// ```
///
@ -621,13 +621,13 @@ fn object_ty_for_trait<'tcx>(
/// Instead, we fudge a little by introducing a new type parameter `U` such that
/// `Self: Unsize<U>` and `U: Trait + ?Sized`, and use `U` in place of `dyn Trait`.
/// Written as a chalk-style query:
///
/// forall (U: Trait + ?Sized) {
/// if (Self: Unsize<U>) {
/// Receiver: DispatchFromDyn<Receiver[Self => U]>
/// }
/// ```ignore (not-rust)
/// forall (U: Trait + ?Sized) {
/// if (Self: Unsize<U>) {
/// Receiver: DispatchFromDyn<Receiver[Self => U]>
/// }
///
/// }
/// ```
/// for `self: &'a mut Self`, this means `&'a mut Self: DispatchFromDyn<&'a mut U>`
/// for `self: Rc<Self>`, this means `Rc<Self>: DispatchFromDyn<Rc<U>>`
/// for `self: Pin<Box<Self>>`, this means `Pin<Box<Self>>: DispatchFromDyn<Pin<Box<U>>>`

View file

@ -158,9 +158,9 @@ pub(super) enum ProjectAndUnifyResult<'tcx> {
}
/// Evaluates constraints of the form:
///
/// for<...> <T as Trait>::U == V
///
/// ```ignore (not-rust)
/// for<...> <T as Trait>::U == V
/// ```
/// If successful, this may result in additional obligations. Also returns
/// the projection cache key used to track these additional obligations.
///
@ -224,9 +224,9 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
}
/// Evaluates constraints of the form:
///
/// <T as Trait>::U == V
///
/// ```ignore (not-rust)
/// <T as Trait>::U == V
/// ```
/// If successful, this may result in additional obligations.
///
/// See [poly_project_and_unify_type] for an explanation of the return value.
@ -1258,7 +1258,7 @@ fn assemble_candidates_from_param_env<'cx, 'tcx>(
/// In the case of a nested projection like <<A as Foo>::FooT as Bar>::BarT, we may find
/// that the definition of `Foo` has some clues:
///
/// ```
/// ```ignore (illustrative)
/// trait Foo {
/// type FooT : Bar<BarT=i32>
/// }

View file

@ -712,9 +712,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// and we desugared it so that the type of the expression is
/// `Closure`, and `Closure` expects `i32` as argument. Then it
/// is "as if" the compiler generated this impl:
///
/// impl Fn(i32) for Closure { ... }
///
/// ```ignore (illustrative)
/// impl Fn(i32) for Closure { ... }
/// ```
/// Now imagine our obligation is `Closure: Fn(usize)`. So far
/// we have matched the self type `Closure`. At this point we'll
/// compare the `i32` to `usize` and generate an error.

View file

@ -1933,7 +1933,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
///
/// Here are some (simple) examples:
///
/// ```
/// ```ignore (illustrative)
/// (i32, u32) -> [i32, u32]
/// Foo where struct Foo { x: i32, y: u32 } -> [i32, u32]
/// Bar<i32> where struct Bar<T> { x: T, y: u32 } -> [i32, u32]

View file

@ -52,7 +52,7 @@ pub struct OverlapError {
///
/// For example, consider the following scenario:
///
/// ```rust
/// ```ignore (illustrative)
/// trait Foo { ... }
/// impl<T, U> Foo for (T, U) { ... } // target impl
/// impl<V> Foo for (V, V) { ... } // source impl
@ -64,7 +64,7 @@ pub struct OverlapError {
/// where-clauses add some trickiness here, because they can be used to "define"
/// an argument indirectly:
///
/// ```rust
/// ```ignore (illustrative)
/// impl<'a, I, T: 'a> Iterator for Cloned<I>
/// where I: Iterator<Item = &'a T>, T: Clone
/// ```

View file

@ -170,7 +170,7 @@ struct WfPredicates<'a, 'tcx> {
/// predicates. This is a kind of hack to address #43784. The
/// underlying problem in that issue was a trait structure like:
///
/// ```
/// ```ignore (illustrative)
/// trait Foo: Copy { }
/// trait Bar: Foo { }
/// impl<T: Bar> Foo for T { }

View file

@ -122,16 +122,16 @@ rustc_index::newtype_index! {
/// A [De Bruijn index][dbi] is a standard means of representing
/// regions (and perhaps later types) in a higher-ranked setting. In
/// particular, imagine a type like this:
///
/// for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char)
/// ^ ^ | | |
/// | | | | |
/// | +------------+ 0 | |
/// | | |
/// +----------------------------------+ 1 |
/// | |
/// +----------------------------------------------+ 0
///
/// ```ignore (illustrative)
/// for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char)
/// // ^ ^ | | |
/// // | | | | |
/// // | +------------+ 0 | |
/// // | | |
/// // +----------------------------------+ 1 |
/// // | |
/// // +----------------------------------------------+ 0
/// ```
/// In this type, there are two binders (the outer fn and the inner
/// fn). We need to be able to determine, for any given region, which
/// fn type it is bound by, the inner or the outer one. There are
@ -203,7 +203,7 @@ impl DebruijnIndex {
/// it will now be bound at INNERMOST. This is an appropriate thing to do
/// when moving a region out from inside binders:
///
/// ```
/// ```ignore (illustrative)
/// for<'a> fn(for<'b> for<'c> fn(&'a u32), _)
/// // Binder: D3 D2 D1 ^^
/// ```
@ -471,9 +471,9 @@ impl Variance {
/// variance with which the argument appears.
///
/// Example 1:
///
/// *mut Vec<i32>
///
/// ```ignore (illustrative)
/// *mut Vec<i32>
/// ```
/// Here, the "ambient" variance starts as covariant. `*mut T` is
/// invariant with respect to `T`, so the variance in which the
/// `Vec<i32>` appears is `Covariant.xform(Invariant)`, which
@ -483,9 +483,9 @@ impl Variance {
/// (again) in `Invariant`.
///
/// Example 2:
///
/// fn(*const Vec<i32>, *mut Vec<i32)
///
/// ```ignore (illustrative)
/// fn(*const Vec<i32>, *mut Vec<i32)
/// ```
/// The ambient variance is covariant. A `fn` type is
/// contravariant with respect to its parameters, so the variance
/// within which both pointer types appear is

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

@ -1467,7 +1467,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
/// }

Some files were not shown because too many files have changed in this diff Show more