Why do I need to import a trait to use the methods it defines for a type?

That’s simply the way it is. In Rust a trait must be in scope for you to be able to call its methods.

As for why, the possibility of collisions is the reason why. All the formatting traits in std::fmt (Display, Debug, LowerHex, &c.) have the same method signature for fmt. For example; what would object.fmt(&mut writer, &mut formatter) do, for example? Rust’s answer is “you must explicitly indicate by having the trait in scope where the method is.”

Note also how the error message says that “no method named `m` found for type `T` in the current scope”.

Note that you don't have to import it if you want to use the trait method as a function instead of a method:

extern crate rustc_serialize;

use rustc_serialize::base64;

fn main() {
    let auth = format!("{}:{}", "user", "password");
    let auth_b64 = rustc_serialize::base64::ToBase64::to_base64(auth.as_bytes(), base64::MIME);
    //             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    println!("Authorization string: {}", auth_b64);
}