HiveBrain v1.2.0
Get Started
← Back to all entries
patternrustMajor

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

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
whydefinesmethodsusethefortypetraitneedimport

Problem

I have a very simple example of Rust code which fails to compile:

extern crate rustc_serialize;
use rustc_serialize::base64;

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


The compiler error:

error[E0599]: no method named to_base64 found for type &[u8] in the current scope
--> src/main.rs:6:36
|
6 | let auth_b64 = auth.as_bytes().to_base64(base64::MIME);
| ^^^^^^^^^
|
= help: items from traits can only be used if the trait is in scope
= note: the following trait is implemented but not in scope, perhaps add a
use for it:
candidate #1:
use rustc_serialize::base64::ToBase64;


It works if I import the trait explicitly:

extern crate rustc_serialize;

use rustc_serialize::base64::{self, ToBase64};

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


Why do I need to use rustc_serialize::base64::ToBase64;?

Solution

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);
}

Code Snippets

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);
}

Context

Stack Overflow Q#25273816, score: 62

Revisions (0)

No revisions yet.