@@ -1193,25 +1193,45 @@ impl Ipv6Addr {
1193
1193
u128:: from_be_bytes ( self . octets ( ) ) == u128:: from_be_bytes ( Ipv6Addr :: UNSPECIFIED . octets ( ) )
1194
1194
}
1195
1195
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`).
1197
1199
///
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`) .
1199
1201
///
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
1201
1205
///
1202
1206
/// # Examples
1203
1207
///
1204
1208
/// ```
1205
1209
/// use std::net::Ipv6Addr;
1206
1210
///
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);
1208
1213
/// 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);
1209
1224
/// ```
1210
1225
#[ rustc_const_stable( feature = "const_ipv6" , since = "1.50.0" ) ]
1211
1226
#[ stable( since = "1.7.0" , feature = "ip_17" ) ]
1227
+ #[ rustc_allow_const_fn_unstable( const_ipv6) ]
1212
1228
#[ inline]
1213
1229
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
+ }
1215
1235
}
1216
1236
1217
1237
/// Returns [`true`] if the address appears to be globally routable.
0 commit comments