Change:
In , reported several NLL errors in dependencies of the servo crate. later minimized one of those errors into : which yields: Removing feature(nll) makes the code work, so probably this is an NLL bug.
I'd like to take a look at this.
Explicitly casting to fixes the issue: My guess is that there's an issue with the automatic coercion from to . I'll investigate further.
It turns out you can remove one layer of indirection and still get the same error:

Discussion:
arg: expr.to_ref(), }, }; <del> ExprKind::Cast { source: expr.to_ref() } </del> <ins> let cast_expr = Expr { temp_lifetime, ty: adjustment.target, span, kind: ExprKind::Cast { source: expr.to_ref() } }; // To ensure that both implicit and explicit coercions are // handled the same way, we insert an extra layer of indirection here. // For explicit casts (e.g. 'foo as *const T'), the source of the 'Use' // will be an ExprKind::Hair with the appropriate cast expression. Here, // we make our Use source the generated Cast from the original coercion. // // In both cases, this outer 'Use' ensures that the inner 'Cast' is handled by // as_operand, not by as_rvalue - causing the cast result to be stored in a temporary. // Ordinary, this is identical to using the cast directly as an rvalue. However, if the // source of the cast was previously borrowed as mutable, storing the cast in a // temporary gives the source a chance to expire before the cast is used. For // structs with a self-referential *mut ptr, this allows assignment to work as // expected. // // For example, consider the type 'struct Foo { field: *mut Foo }', // The method 'fn bar(&mut self) { self.field = self }' // triggers a coercion from '&mut self' to '*mut self'. In order // for the assignment to be valid, the implicit borrow // of 'self' involved in the coercion needs to end before the local // containing the '*mut T' is assigned to 'self.field' - otherwise, // we end up trying to assign to 'self.field' while we have another mutable borrow // active. // // We only need to worry about this kind of thing for coercions from refs to ptrs, // since they get rid of a borrow implicitly. ExprKind::Use { source: cast_expr.to_ref() } </ins> } Adjust::Unsize => { ExprKind::Unsize { source: expr.to_ref() }

//         Validate(Acquire, [_1: &ReFree(DefId(0/1:9 ~ validate_5[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(46)], _2: &ReFree(DefId(0/1:9 ~ validate_5[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); //         StorageLive(_3); //         StorageLive(_4); <ins> //         StorageLive(_5); </ins> //         Validate(Suspend(ReScope(Node(ItemLocalId(9)))), [(*_2): i32]); <del> //         _4 = &ReErased mut (*_2); //         Validate(Acquire, [(*_4): i32/ReScope(Node(ItemLocalId(9)))]); //         _3 = move _4 as *mut i32 (Misc); </del> <ins> //         _5 = &ReErased mut (*_2); //         Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(9)))]); //         _4 = move _5 as *mut i32 (Misc); //         _3 = move _4; </ins> //         EndRegion(ReScope(Node(ItemLocalId(9)))); //         StorageDead(_4); <ins> //         StorageDead(_5); </ins> //         Validate(Release, [_0: bool, _3: *mut i32]); //         _0 = const write_42(move _3) -> bb1; //     }

<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // // Tests that automatic coercions from &mut T to *mut T // allow borrows of T to expire immediately - essentially, that // they work identically to 'foo as *mut T' #![feature(nll)] struct SelfReference { self_reference: *mut SelfReference, } impl SelfReference { fn set_self_ref(&mut self) { self.self_reference = self; } } fn main() {} </ins>