X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;ds=sidebyside;f=compiler%2Frustc_middle%2Fsrc%2Fmir%2Fmod.rs;h=b357a657b5981de15a7752bfd3fd2457a8aaae37;hb=7907385999b4a83d37ed31d334f3ed9ca02983a1;hp=881f59ae464c93ababca1442fe0a67e7f2909d7b;hpb=7417110cefda899a685a77557ac2bd7d7ee07e54;p=rust.git diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 881f59ae464..b357a657b59 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -62,7 +62,9 @@ mod switch_sources; pub mod tcx; pub mod terminator; +use crate::mir::traversal::PostorderCache; pub use terminator::*; + pub mod traversal; mod type_foldable; pub mod visit; @@ -323,6 +325,7 @@ pub struct Body<'tcx> { predecessor_cache: PredecessorCache, switch_source_cache: SwitchSourceCache, is_cyclic: GraphIsCyclicCache, + postorder_cache: PostorderCache, pub tainted_by_errors: Option, } @@ -372,6 +375,7 @@ pub fn new( predecessor_cache: PredecessorCache::new(), switch_source_cache: SwitchSourceCache::new(), is_cyclic: GraphIsCyclicCache::new(), + postorder_cache: PostorderCache::new(), tainted_by_errors, }; body.is_polymorphic = body.has_param_types_or_consts(); @@ -401,6 +405,7 @@ pub fn new_cfg_only(basic_blocks: IndexVec>) -> predecessor_cache: PredecessorCache::new(), switch_source_cache: SwitchSourceCache::new(), is_cyclic: GraphIsCyclicCache::new(), + postorder_cache: PostorderCache::new(), tainted_by_errors: None, }; body.is_polymorphic = body.has_param_types_or_consts(); @@ -422,6 +427,7 @@ pub fn basic_blocks_mut(&mut self) -> &mut IndexVec (), - /// 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`. @@ -747,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 @@ -1008,7 +1019,7 @@ pub struct LocalDecl<'tcx> { /// ``` /// fn foo(x: &str) { /// match { - /// match x.parse().unwrap() { + /// match x.parse::().unwrap() { /// y => y + 2 /// } /// } { @@ -1682,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: /// @@ -1977,7 +1988,7 @@ pub enum ProjectionElem { /// 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 }, @@ -2581,8 +2592,6 @@ pub enum Rvalue<'tcx> { /// This is different from a normal transmute because dataflow analysis will treat the box as /// initialized but its content as uninitialized. Like other pointer casts, this in general /// affects alias analysis. - /// - /// Disallowed after drop elaboration. ShallowInitBox(Operand<'tcx>, Ty<'tcx>), } @@ -3173,7 +3182,7 @@ fn from_opt_const_arg_anon_const( /// /// An example: /// -/// ```rust +/// ```ignore (illustrative) /// struct S<'a>((i32, &'a str), String); /// let S((_, w): (i32, &'static str), _): S = ...; /// // ------ ^^^^^^^^^^^^^^^^^^^ (1)