@@ -1193,25 +1193,45 @@ impl Ipv6Addr {
11931193 u128:: from_be_bytes ( self . octets ( ) ) == u128:: from_be_bytes ( Ipv6Addr :: UNSPECIFIED . octets ( ) )
11941194 }
11951195
1196- /// Returns [`true`] if this is a loopback address (::1).
1196+ /// Returns [`true`] if this is either:
1197+ /// - the [loopback address] as defined in [IETF RFC 4291 section 2.5.3] (`::1`).
1198+ /// - an IPv4-mapped address representing an IPv4 loopback address as defined in [IETF RFC 1122] (`::ffff:127.0.0.0/104`).
11971199 ///
1198- /// This property is defined in [IETF RFC 4291] .
1200+ /// Note that this returns [`false`] for an IPv4-compatible address representing an IPv4 loopback address (`::127.0.0.0/104`) .
11991201 ///
1200- /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
1202+ /// [loopback address]: Ipv6Addr::LOCALHOST
1203+ /// [IETF RFC 4291 section 2.5.3]: https://tools.ietf.org/html/rfc4291#section-2.5.3
1204+ /// [IETF RFC 1122]: https://tools.ietf.org/html/rfc1122
12011205 ///
12021206 /// # Examples
12031207 ///
12041208 /// ```
12051209 /// use std::net::Ipv6Addr;
12061210 ///
1207- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_loopback(), false);
1211+ /// // `true` for the IPv6 loopback address (`::1`)
1212+ /// assert_eq!(Ipv6Addr::LOCALHOST.is_loopback(), true);
12081213 /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_loopback(), true);
1214+ ///
1215+ /// use std::net::Ipv4Addr;
1216+ ///
1217+ /// // `true` for an IPv4-mapped address representing an IPv4 loopback address (`::ffff:127.0.0.1`)
1218+ /// assert_eq!(Ipv4Addr::LOCALHOST.to_ipv6_mapped().is_loopback(), true);
1219+ /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1).is_loopback(), true);
1220+ ///
1221+ /// // `false` for an IPv4-compatible address representing an IPv4 loopback address (`::127.0.0.1`)
1222+ /// assert_eq!(Ipv4Addr::LOCALHOST.to_ipv6_compatible().is_loopback(), false);
1223+ /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x7f00, 0x1).is_loopback(), false);
12091224 /// ```
12101225 #[ rustc_const_stable( feature = "const_ipv6" , since = "1.50.0" ) ]
12111226 #[ stable( since = "1.7.0" , feature = "ip_17" ) ]
1227+ #[ rustc_allow_const_fn_unstable( const_ipv6) ]
12121228 #[ inline]
12131229 pub const fn is_loopback ( & self ) -> bool {
1214- u128:: from_be_bytes ( self . octets ( ) ) == u128:: from_be_bytes ( Ipv6Addr :: LOCALHOST . octets ( ) )
1230+ if let Some ( ipv4) = self . to_ipv4_mapped ( ) {
1231+ ipv4. is_loopback ( )
1232+ } else {
1233+ u128:: from_be_bytes ( self . octets ( ) ) == u128:: from_be_bytes ( Ipv6Addr :: LOCALHOST . octets ( ) )
1234+ }
12151235 }
12161236
12171237 /// Returns [`true`] if the address appears to be globally routable.
0 commit comments