From 2f98f4b12b8fd5d93ffff3d7b98931b3f1f2b07a Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 23 Jan 2018 16:31:53 +0100 Subject: [PATCH 1/5] Move PanicInfo and Location to libcore Per https://rust-lang.github.io/rfcs/2070-panic-implementation.html --- src/libcore/lib.rs | 1 + src/libcore/panic.rs | 213 ++++++++++++++++++++++++++++++++++++++++ src/libstd/lib.rs | 1 + src/libstd/panic.rs | 5 +- src/libstd/panicking.rs | 200 +++---------------------------------- 5 files changed, 230 insertions(+), 190 deletions(-) create mode 100644 src/libcore/panic.rs diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index d5190b65863cb..11476a05dd353 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -158,6 +158,7 @@ pub mod array; pub mod sync; pub mod cell; pub mod char; +pub mod panic; pub mod panicking; pub mod iter; pub mod option; diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs new file mode 100644 index 0000000000000..dbfe531063b7d --- /dev/null +++ b/src/libcore/panic.rs @@ -0,0 +1,213 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Panic support in the standard library. + +#![unstable(feature = "core_panic_info", + reason = "newly available in libcore", + issue = "44489")] + +use any::Any; + +/// A struct providing information about a panic. +/// +/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`] +/// function. +/// +/// [`set_hook`]: ../../std/panic/fn.set_hook.html +/// +/// # Examples +/// +/// ```should_panic +/// use std::panic; +/// +/// panic::set_hook(Box::new(|panic_info| { +/// println!("panic occurred: {:?}", panic_info.payload().downcast_ref::<&str>().unwrap()); +/// })); +/// +/// panic!("Normal panic"); +/// ``` +#[stable(feature = "panic_hooks", since = "1.10.0")] +#[derive(Debug)] +pub struct PanicInfo<'a> { + payload: &'a (Any + Send), + location: Location<'a>, +} + +impl<'a> PanicInfo<'a> { + #![unstable(feature = "panic_internals", + reason = "internal details of the implementation of the `panic!` \ + and related macros", + issue = "0")] + #[doc(hidden)] + pub fn internal_constructor(payload: &'a (Any + Send), location: Location<'a>,) -> Self { + PanicInfo { payload, location } + } + + /// Returns the payload associated with the panic. + /// + /// This will commonly, but not always, be a `&'static str` or [`String`]. + /// + /// [`String`]: ../../std/string/struct.String.html + /// + /// # Examples + /// + /// ```should_panic + /// use std::panic; + /// + /// panic::set_hook(Box::new(|panic_info| { + /// println!("panic occurred: {:?}", panic_info.payload().downcast_ref::<&str>().unwrap()); + /// })); + /// + /// panic!("Normal panic"); + /// ``` + #[stable(feature = "panic_hooks", since = "1.10.0")] + pub fn payload(&self) -> &(Any + Send) { + self.payload + } + + /// Returns information about the location from which the panic originated, + /// if available. + /// + /// This method will currently always return [`Some`], but this may change + /// in future versions. + /// + /// [`Some`]: ../../std/option/enum.Option.html#variant.Some + /// + /// # Examples + /// + /// ```should_panic + /// use std::panic; + /// + /// panic::set_hook(Box::new(|panic_info| { + /// if let Some(location) = panic_info.location() { + /// println!("panic occurred in file '{}' at line {}", location.file(), + /// location.line()); + /// } else { + /// println!("panic occurred but can't get location information..."); + /// } + /// })); + /// + /// panic!("Normal panic"); + /// ``` + #[stable(feature = "panic_hooks", since = "1.10.0")] + pub fn location(&self) -> Option<&Location> { + // NOTE: If this is changed to sometimes return None, + // deal with that case in std::panicking::default_hook. + Some(&self.location) + } +} + +/// A struct containing information about the location of a panic. +/// +/// This structure is created by the [`location`] method of [`PanicInfo`]. +/// +/// [`location`]: ../../std/panic/struct.PanicInfo.html#method.location +/// [`PanicInfo`]: ../../std/panic/struct.PanicInfo.html +/// +/// # Examples +/// +/// ```should_panic +/// use std::panic; +/// +/// panic::set_hook(Box::new(|panic_info| { +/// if let Some(location) = panic_info.location() { +/// println!("panic occurred in file '{}' at line {}", location.file(), location.line()); +/// } else { +/// println!("panic occurred but can't get location information..."); +/// } +/// })); +/// +/// panic!("Normal panic"); +/// ``` +#[derive(Debug)] +#[stable(feature = "panic_hooks", since = "1.10.0")] +pub struct Location<'a> { + file: &'a str, + line: u32, + col: u32, +} + +impl<'a> Location<'a> { + #![unstable(feature = "panic_internals", + reason = "internal details of the implementation of the `panic!` \ + and related macros", + issue = "0")] + #[doc(hidden)] + pub fn internal_constructor(file: &'a str, line: u32, col: u32) -> Self { + Location { file, line, col } + } + + /// Returns the name of the source file from which the panic originated. + /// + /// # Examples + /// + /// ```should_panic + /// use std::panic; + /// + /// panic::set_hook(Box::new(|panic_info| { + /// if let Some(location) = panic_info.location() { + /// println!("panic occurred in file '{}'", location.file()); + /// } else { + /// println!("panic occurred but can't get location information..."); + /// } + /// })); + /// + /// panic!("Normal panic"); + /// ``` + #[stable(feature = "panic_hooks", since = "1.10.0")] + pub fn file(&self) -> &str { + self.file + } + + /// Returns the line number from which the panic originated. + /// + /// # Examples + /// + /// ```should_panic + /// use std::panic; + /// + /// panic::set_hook(Box::new(|panic_info| { + /// if let Some(location) = panic_info.location() { + /// println!("panic occurred at line {}", location.line()); + /// } else { + /// println!("panic occurred but can't get location information..."); + /// } + /// })); + /// + /// panic!("Normal panic"); + /// ``` + #[stable(feature = "panic_hooks", since = "1.10.0")] + pub fn line(&self) -> u32 { + self.line + } + + /// Returns the column from which the panic originated. + /// + /// # Examples + /// + /// ```should_panic + /// use std::panic; + /// + /// panic::set_hook(Box::new(|panic_info| { + /// if let Some(location) = panic_info.location() { + /// println!("panic occurred at column {}", location.column()); + /// } else { + /// println!("panic occurred but can't get location information..."); + /// } + /// })); + /// + /// panic!("Normal panic"); + /// ``` + #[stable(feature = "panic_col", since = "1.25")] + pub fn column(&self) -> u32 { + self.col + } +} diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 91cc6d25cce01..4b374dc140730 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -288,6 +288,7 @@ #![feature(on_unimplemented)] #![feature(oom)] #![feature(optin_builtin_traits)] +#![feature(panic_internals)] #![feature(panic_unwind)] #![feature(peek)] #![feature(placement_in_syntax)] diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 560876006d3f3..566ef16f29534 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -23,7 +23,10 @@ use sync::{Arc, Mutex, RwLock, atomic}; use thread::Result; #[stable(feature = "panic_hooks", since = "1.10.0")] -pub use panicking::{take_hook, set_hook, PanicInfo, Location}; +pub use panicking::{take_hook, set_hook}; + +#[stable(feature = "panic_hooks", since = "1.10.0")] +pub use core::panic::{PanicInfo, Location}; /// A marker trait which represents "panic safe" types in Rust. /// diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index f91eaf433d766..a748c89f9d4fa 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -21,6 +21,7 @@ use io::prelude::*; use any::Any; use cell::RefCell; +use core::panic::{PanicInfo, Location}; use fmt; use intrinsics; use mem; @@ -158,182 +159,6 @@ pub fn take_hook() -> Box { } } -/// A struct providing information about a panic. -/// -/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`] -/// function. -/// -/// [`set_hook`]: ../../std/panic/fn.set_hook.html -/// -/// # Examples -/// -/// ```should_panic -/// use std::panic; -/// -/// panic::set_hook(Box::new(|panic_info| { -/// println!("panic occurred: {:?}", panic_info.payload().downcast_ref::<&str>().unwrap()); -/// })); -/// -/// panic!("Normal panic"); -/// ``` -#[stable(feature = "panic_hooks", since = "1.10.0")] -#[derive(Debug)] -pub struct PanicInfo<'a> { - payload: &'a (Any + Send), - location: Location<'a>, -} - -impl<'a> PanicInfo<'a> { - /// Returns the payload associated with the panic. - /// - /// This will commonly, but not always, be a `&'static str` or [`String`]. - /// - /// [`String`]: ../../std/string/struct.String.html - /// - /// # Examples - /// - /// ```should_panic - /// use std::panic; - /// - /// panic::set_hook(Box::new(|panic_info| { - /// println!("panic occurred: {:?}", panic_info.payload().downcast_ref::<&str>().unwrap()); - /// })); - /// - /// panic!("Normal panic"); - /// ``` - #[stable(feature = "panic_hooks", since = "1.10.0")] - pub fn payload(&self) -> &(Any + Send) { - self.payload - } - - /// Returns information about the location from which the panic originated, - /// if available. - /// - /// This method will currently always return [`Some`], but this may change - /// in future versions. - /// - /// [`Some`]: ../../std/option/enum.Option.html#variant.Some - /// - /// # Examples - /// - /// ```should_panic - /// use std::panic; - /// - /// panic::set_hook(Box::new(|panic_info| { - /// if let Some(location) = panic_info.location() { - /// println!("panic occurred in file '{}' at line {}", location.file(), - /// location.line()); - /// } else { - /// println!("panic occurred but can't get location information..."); - /// } - /// })); - /// - /// panic!("Normal panic"); - /// ``` - #[stable(feature = "panic_hooks", since = "1.10.0")] - pub fn location(&self) -> Option<&Location> { - Some(&self.location) - } -} - -/// A struct containing information about the location of a panic. -/// -/// This structure is created by the [`location`] method of [`PanicInfo`]. -/// -/// [`location`]: ../../std/panic/struct.PanicInfo.html#method.location -/// [`PanicInfo`]: ../../std/panic/struct.PanicInfo.html -/// -/// # Examples -/// -/// ```should_panic -/// use std::panic; -/// -/// panic::set_hook(Box::new(|panic_info| { -/// if let Some(location) = panic_info.location() { -/// println!("panic occurred in file '{}' at line {}", location.file(), location.line()); -/// } else { -/// println!("panic occurred but can't get location information..."); -/// } -/// })); -/// -/// panic!("Normal panic"); -/// ``` -#[derive(Debug)] -#[stable(feature = "panic_hooks", since = "1.10.0")] -pub struct Location<'a> { - file: &'a str, - line: u32, - col: u32, -} - -impl<'a> Location<'a> { - /// Returns the name of the source file from which the panic originated. - /// - /// # Examples - /// - /// ```should_panic - /// use std::panic; - /// - /// panic::set_hook(Box::new(|panic_info| { - /// if let Some(location) = panic_info.location() { - /// println!("panic occurred in file '{}'", location.file()); - /// } else { - /// println!("panic occurred but can't get location information..."); - /// } - /// })); - /// - /// panic!("Normal panic"); - /// ``` - #[stable(feature = "panic_hooks", since = "1.10.0")] - pub fn file(&self) -> &str { - self.file - } - - /// Returns the line number from which the panic originated. - /// - /// # Examples - /// - /// ```should_panic - /// use std::panic; - /// - /// panic::set_hook(Box::new(|panic_info| { - /// if let Some(location) = panic_info.location() { - /// println!("panic occurred at line {}", location.line()); - /// } else { - /// println!("panic occurred but can't get location information..."); - /// } - /// })); - /// - /// panic!("Normal panic"); - /// ``` - #[stable(feature = "panic_hooks", since = "1.10.0")] - pub fn line(&self) -> u32 { - self.line - } - - /// Returns the column from which the panic originated. - /// - /// # Examples - /// - /// ```should_panic - /// use std::panic; - /// - /// panic::set_hook(Box::new(|panic_info| { - /// if let Some(location) = panic_info.location() { - /// println!("panic occurred at column {}", location.column()); - /// } else { - /// println!("panic occurred but can't get location information..."); - /// } - /// })); - /// - /// panic!("Normal panic"); - /// ``` - #[stable(feature = "panic_col", since = "1.25")] - pub fn column(&self) -> u32 { - self.col - } -} - fn default_hook(info: &PanicInfo) { #[cfg(feature = "backtrace")] use sys_common::backtrace; @@ -351,13 +176,14 @@ fn default_hook(info: &PanicInfo) { } }; - let file = info.location.file; - let line = info.location.line; - let col = info.location.col; + let location = info.location().unwrap(); // The current implementation always returns Some + let file = location.file(); + let line = location.line(); + let col = location.column(); - let msg = match info.payload.downcast_ref::<&'static str>() { + let msg = match info.payload().downcast_ref::<&'static str>() { Some(s) => *s, - None => match info.payload.downcast_ref::() { + None => match info.payload().downcast_ref::() { Some(s) => &s[..], None => "Box", } @@ -563,14 +389,10 @@ fn rust_panic_with_hook(msg: Box, } unsafe { - let info = PanicInfo { - payload: &*msg, - location: Location { - file, - line, - col, - }, - }; + let info = PanicInfo::internal_constructor( + &*msg, + Location::internal_constructor(file, line, col), + ); HOOK_LOCK.read(); match HOOK { Hook::Default => default_hook(&info), From 9e96c1ef7fcac0ac85b3c9160f5486e91dd27dd2 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 23 Jan 2018 17:24:19 +0100 Subject: [PATCH 2/5] Add an unstable PanicInfo::message(&self) -> Option<&fmt::Arguments> method --- src/libcore/panic.rs | 19 +++++++++++++++++-- src/libstd/panicking.rs | 1 + 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs index dbfe531063b7d..2dfd950225c36 100644 --- a/src/libcore/panic.rs +++ b/src/libcore/panic.rs @@ -15,6 +15,7 @@ issue = "44489")] use any::Any; +use fmt; /// A struct providing information about a panic. /// @@ -38,6 +39,7 @@ use any::Any; #[derive(Debug)] pub struct PanicInfo<'a> { payload: &'a (Any + Send), + message: Option<&'a fmt::Arguments<'a>>, location: Location<'a>, } @@ -47,8 +49,11 @@ impl<'a> PanicInfo<'a> { and related macros", issue = "0")] #[doc(hidden)] - pub fn internal_constructor(payload: &'a (Any + Send), location: Location<'a>,) -> Self { - PanicInfo { payload, location } + pub fn internal_constructor(payload: &'a (Any + Send), + message: Option<&'a fmt::Arguments<'a>>, + location: Location<'a>) + -> Self { + PanicInfo { payload, location, message } } /// Returns the payload associated with the panic. @@ -73,6 +78,16 @@ impl<'a> PanicInfo<'a> { self.payload } + /// If the `panic!` macro from the `core` crate (not from `std`) + /// was used with a formatting string and some additional arguments, + /// returns that message ready to be used for example with [`fmt::write`] + /// + /// [`fmt::write`]: ../fmt/fn.write.html + #[unstable(feature = "panic_info_message", issue = "44489")] + pub fn message(&self) -> Option<&fmt::Arguments> { + self.message + } + /// Returns information about the location from which the panic originated, /// if available. /// diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index a748c89f9d4fa..3f5523548ce57 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -391,6 +391,7 @@ fn rust_panic_with_hook(msg: Box, unsafe { let info = PanicInfo::internal_constructor( &*msg, + None, Location::internal_constructor(file, line, col), ); HOOK_LOCK.read(); From 0e60287b4136bcede0c5eae8ab4e5de8496a16f0 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 23 Jan 2018 17:49:43 +0100 Subject: [PATCH 3/5] Implement Display for PanicInfo and Location MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Due to being in libcore, this impl cannot access PanicInfo::payload if it’s a String. --- src/libcore/panic.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs index 2dfd950225c36..cf8ceff6cda0d 100644 --- a/src/libcore/panic.rs +++ b/src/libcore/panic.rs @@ -120,6 +120,23 @@ impl<'a> PanicInfo<'a> { } } +impl<'a> fmt::Display for PanicInfo<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("panicked at ")?; + if let Some(message) = self.message { + write!(formatter, "'{}', ", message)? + } else if let Some(payload) = self.payload.downcast_ref::<&'static str>() { + write!(formatter, "'{}', ", payload)? + } + // NOTE: we cannot use downcast_ref::() here + // since String is not available in libcore! + // A String payload and no message is what we’d get from `std::panic!` + // called with multiple arguments. + + self.location.fmt(formatter) + } +} + /// A struct containing information about the location of a panic. /// /// This structure is created by the [`location`] method of [`PanicInfo`]. @@ -226,3 +243,9 @@ impl<'a> Location<'a> { self.col } } + +impl<'a> fmt::Display for Location<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "{}:{}:{}", self.file, self.line, self.col) + } +} From f15c8169327244730f8e68598bf85d288e16fd70 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 23 Jan 2018 18:19:21 +0100 Subject: [PATCH 4/5] Make PanicInfo::message available for std::panic! with a formatting string. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This enables PanicInfo’s Display impl to show the panic message in those cases. --- src/libcore/panic.rs | 4 ++-- src/libstd/panicking.rs | 13 +++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs index cf8ceff6cda0d..14eb68d9b95b5 100644 --- a/src/libcore/panic.rs +++ b/src/libcore/panic.rs @@ -130,8 +130,8 @@ impl<'a> fmt::Display for PanicInfo<'a> { } // NOTE: we cannot use downcast_ref::() here // since String is not available in libcore! - // A String payload and no message is what we’d get from `std::panic!` - // called with multiple arguments. + // The payload is a String when `std::panic!` is called with multiple arguments, + // but in that case the message is also available. self.location.fmt(formatter) } diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 3f5523548ce57..161c3fc7113a7 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -344,7 +344,7 @@ pub fn begin_panic_fmt(msg: &fmt::Arguments, let mut s = String::new(); let _ = s.write_fmt(*msg); - begin_panic(s, file_line_col) + rust_panic_with_hook(Box::new(s), Some(msg), file_line_col) } /// This is the entry point of panicking for panic!() and assert!(). @@ -360,7 +360,7 @@ pub fn begin_panic(msg: M, file_line_col: &(&'static str, u32, u3 // be performed in the parent of this thread instead of the thread that's // panicking. - rust_panic_with_hook(Box::new(msg), file_line_col) + rust_panic_with_hook(Box::new(msg), None, file_line_col) } /// Executes the primary logic for a panic, including checking for recursive @@ -371,7 +371,8 @@ pub fn begin_panic(msg: M, file_line_col: &(&'static str, u32, u3 /// run panic hooks, and then delegate to the actual implementation of panics. #[inline(never)] #[cold] -fn rust_panic_with_hook(msg: Box, +fn rust_panic_with_hook(payload: Box, + message: Option<&fmt::Arguments>, file_line_col: &(&'static str, u32, u32)) -> ! { let (file, line, col) = *file_line_col; @@ -390,8 +391,8 @@ fn rust_panic_with_hook(msg: Box, unsafe { let info = PanicInfo::internal_constructor( - &*msg, - None, + &*payload, + message, Location::internal_constructor(file, line, col), ); HOOK_LOCK.read(); @@ -412,7 +413,7 @@ fn rust_panic_with_hook(msg: Box, unsafe { intrinsics::abort() } } - rust_panic(msg) + rust_panic(payload) } /// Shim around rust_panic. Called by resume_unwind. From 399dcd112725a35352075262863781b3355452cd Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 24 Jan 2018 22:25:42 +0100 Subject: [PATCH 5/5] Add missing micro version number component in stability attributes. --- src/liballoc/heap.rs | 2 +- src/libcore/panic.rs | 2 +- src/libcore/ptr.rs | 2 +- src/libstd/net/mod.rs | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index 37af9ea529532..372d606e45722 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -232,7 +232,7 @@ unsafe impl Alloc for Heap { /// /// This preserves the non-null invariant for types like `Box`. The address /// may overlap with non-zero-size memory allocations. -#[rustc_deprecated(since = "1.19", reason = "Use Unique/NonNull::empty() instead")] +#[rustc_deprecated(since = "1.19.0", reason = "Use Unique/NonNull::empty() instead")] #[unstable(feature = "heap_api", issue = "27700")] pub const EMPTY: *mut () = 1 as *mut (); diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs index 14eb68d9b95b5..4e72eaa57c73e 100644 --- a/src/libcore/panic.rs +++ b/src/libcore/panic.rs @@ -238,7 +238,7 @@ impl<'a> Location<'a> { /// /// panic!("Normal panic"); /// ``` - #[stable(feature = "panic_col", since = "1.25")] + #[stable(feature = "panic_col", since = "1.25.0")] pub fn column(&self) -> u32 { self.col } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index fab5832d905df..2c1dfb136333f 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2461,7 +2461,7 @@ impl<'a, T: ?Sized> From> for Unique { } /// Previous name of `NonNull`. -#[rustc_deprecated(since = "1.24", reason = "renamed to `NonNull`")] +#[rustc_deprecated(since = "1.25.0", reason = "renamed to `NonNull`")] #[unstable(feature = "shared", issue = "27730")] pub type Shared = NonNull; diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs index eb0e2e13b4cd2..eef043683b02e 100644 --- a/src/libstd/net/mod.rs +++ b/src/libstd/net/mod.rs @@ -134,14 +134,14 @@ fn each_addr(addr: A, mut f: F) -> io::Result iterator and returning socket \ addresses", issue = "27705")] -#[rustc_deprecated(since = "1.25", reason = "Use the ToSocketAddrs trait instead")] +#[rustc_deprecated(since = "1.25.0", reason = "Use the ToSocketAddrs trait instead")] pub struct LookupHost(net_imp::LookupHost); #[unstable(feature = "lookup_host", reason = "unsure about the returned \ iterator and returning socket \ addresses", issue = "27705")] -#[rustc_deprecated(since = "1.25", reason = "Use the ToSocketAddrs trait instead")] +#[rustc_deprecated(since = "1.25.0", reason = "Use the ToSocketAddrs trait instead")] #[allow(deprecated)] impl Iterator for LookupHost { type Item = SocketAddr; @@ -152,7 +152,7 @@ impl Iterator for LookupHost { iterator and returning socket \ addresses", issue = "27705")] -#[rustc_deprecated(since = "1.25", reason = "Use the ToSocketAddrs trait instead")] +#[rustc_deprecated(since = "1.25.0", reason = "Use the ToSocketAddrs trait instead")] #[allow(deprecated)] impl fmt::Debug for LookupHost { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -186,7 +186,7 @@ impl fmt::Debug for LookupHost { iterator and returning socket \ addresses", issue = "27705")] -#[rustc_deprecated(since = "1.25", reason = "Use the ToSocketAddrs trait instead")] +#[rustc_deprecated(since = "1.25.0", reason = "Use the ToSocketAddrs trait instead")] #[allow(deprecated)] pub fn lookup_host(host: &str) -> io::Result { net_imp::lookup_host(host).map(LookupHost)