Code change:
pub fn read_line(&self, buf: &mut String) -> io::Result<usize> { self.lock().read_line(buf) } <ins> // Locks this handle with any lifetime. This depends on the // implementation detail that the underlying `Mutex` is static. fn lock_any<'a>(&self) -> StdinLock<'a> { StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } } /// Consumes this handle to the standard input stream, locking the /// shared global buffer associated with the stream and returning a /// readable guard. /// /// The lock is released when the returned guard goes out of scope. The /// returned guard also implements the [`Read`] and [`BufRead`] traits /// for accessing the underlying data. /// /// It is often simpler to directly get a locked handle using the /// [`stdin_locked`] function instead, unless nearby code also needs to /// use an unlocked handle. /// /// # Examples /// /// ```no_run /// #![feature(stdio_locked)] /// use std::io::{self, Read}; /// /// fn main() -> io::Result<()> { ///     let mut buffer = String::new(); ///     let mut handle = io::stdin().into_locked(); /// ///     handle.read_to_string(&mut buffer)?; ///     Ok(()) /// } /// ``` #[unstable(feature = "stdio_locked", issue = "none")] pub fn into_locked(self) -> StdinLock<'static> { self.lock_any() } </ins> } #[stable(feature = "std_debug", since = "1.16.0")]

Related discussion:
text: Given the following code: The current output is: I think it's typical for a newcomer to want to get a iterator by chaining method calls like . There's no obvious reason why that shouldn't work. The examples in the documentation do typically show being assigned to a variable prior to calling its method, but don't explain why that's necessary. I think the "borrow" terminology is misleading, but there might not be a concise way to describe what's actually going on to the user. The "temporary value is freed at the end of this statement" is probably correct. The "creates a temporary which is freed while still in use" is probably more correctly "creates a temporary that is required to outlive (or live exactly as long as) the result of...", followed by a pointer to the method invocation, with text of " method call". Maybe it should also point out the lifetime argument in the return type. I tried and failed to find a satisfactory explanation of what exactly was borrowing from the temporary value produced by . When I looked through the library source code, the only references in were those created by locking a , and the in question is static. I'm guessing the existence of a borrow is assumed rather than inferred from analyzing the function body of . The assumption might be the result of the anonymous lifetime argument on the output type from , which imposes a requirement that the doesn't outlive (or has the same lifetime as?) the value that is the receiver of . The correct fix might be to change the locked stdin handles to all use lifetimes, but I will probably file that as a separate issue.
label +A-borrow-checker +A-lifetimes +D-confusing +D-incorrect +D-newcomer-roadblock
IMO the intent is clear here. Without changing the API, why exactly is Rust unable to lift 'a &'static X to 'static & 'static X, if X also contains only 'static lifetimes? I don't think raw references have a meaningful dropper; borrowck is able to freely resolve any derived lifetimes on impls that don't depend on anything else to 'static; I'm pretty sure under current rules we should be able to substitute latter for earlier and get exactly the same behaviour.
This is due to .