Extending Foreign Types
An extension trait is a local trait definition whose primary purpose is to attach new methods to foreign types.
// Copyright 2025 Google LLC // SPDX-License-Identifier: Apache-2.0 mod ext { pub trait StrExt { fn is_palindrome(&self) -> bool; } impl StrExt for str { fn is_palindrome(&self) -> bool { self.chars().eq(self.chars().rev()) } } } fn main() { // Bring the extension trait into scope... pub use ext::StrExt as _; // ...then invoke its methods as if they were inherent methods assert!("dad".is_palindrome()); assert!(!"grandma".is_palindrome()); }
-
The
Extsuffix is conventionally attached to the name of extension traits.It communicates that the trait is primarily used for extension purposes, and it is therefore not intended to be implemented outside the crate that defines it.
Refer to the âExtension Traitâ RFC as the authoritative source for naming conventions.
-
The extension trait implementation for a foreign type must be in the same crate as the trait itself, otherwise youâll be blocked by Rustâs orphan rule.
-
The extension trait must be in scope when its methods are invoked.
Comment out the
usestatement in the example to show the compiler error thatâs emitted if you try to invoke an extension method without having the corresponding extension trait in scope. -
The example above uses an underscore import (
use ext::StringExt as _) to minimize the likelihood of a naming conflict with other imported traits.With an underscore import, the trait is considered to be in scope and youâre allowed to invoke its methods on types that implement the trait. Its symbol, instead, is not directly accessible. This prevents you, for example, from using that trait in a
whereclause.Since extension traits arenât meant to be used in
whereclauses, they are conventionally imported via an underscore import.