Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of undeclared type or module core::fmt::Display

Tags:

rust

I have some code that works fine with exact types, but when I add generics it throws an error.

It gives me the following error, my code is below:

The trait core::fmt::Display is not implemented for the type T [E0277]

fn own<T>(x: T) -> T 
{ 
    x 
}

struct Node<T>
{
    value: T,
    next: Option<Box<Node<T>>>
}

impl<T> Node<T>
{
    fn print(&self)
    {
        let mut current = self;
        loop {
            println!("{}", current.value);
            match current.next {
                Some(ref next) => { current = &**next; },
                None => break,
            }
        } 
    }
    
    fn add(&mut self, node: Node<T>)
    {
        let item = Some(Box::new(node));
        let mut current = self;
        loop {
            match own(current).next {
                ref mut slot @ None => { *slot = item; return },
                Some(ref mut next) => current = next
            }
        } 
    }
}

fn main() {  
    let leaf = Node { value: 10, next: None };
    let branch = Node { value : 50, next: Some(Box::new(leaf)) };
    let mut root = Node { value : 100, next: Some(Box::new(branch)) };
    root.print(); 
    
    let new_leaf = Node { value: 5, next: None };
    root.add(new_leaf);
    root.print();
}

I understand that this is a common error for generics in all languages, but when I try to add constraints to generics I get another error:

<anon>:12:8: 12:26 error: failed to resolve. Use of undeclared type or module core::fmt

<anon>:12 impl<T:core::fmt::Display> Node<T>

Why does it appear if I have copied the full qualified name from error and inserted it as a constraint?
It also doesn't work with another traits, for example impl<T:Num>

(Playground)

like image 851
Alex Zhukovskiy Avatar asked May 26 '15 15:05

Alex Zhukovskiy


1 Answers

This is an ugly wart of Rust, and I hope it gets addressed some day. The short version is that you want std::fmt::Display, not core::fmt::Display:

impl<T> Node<T>
where
    T: std::fmt::Display,
{
    // ...
}

The longer answer is that the Rust standard library is split into two parts: std and core. core is a lower-level library (emphasis mine):

The Rust Core Library is the dependency-free foundation of The Rust Standard Library. It is the portable glue between the language and its libraries, defining the intrinsic and primitive building blocks of all Rust code. It links to no upstream libraries, no system libraries, and no libc.

The core library is minimal: it isn't even aware of heap allocation, nor does it provide concurrency or I/O. These things require platform integration, and this library is platform-agnostic.

It is not recommended to use the core library. The stable functionality of libcore is reexported from the standard library. The composition of this library is subject to change over time; only the interface exposed through libstd is intended to be stable.

It would be silly to implement items once in core and once in std, so the standard library re-exports the items from core under itself. However, the code from core knows itself as core, not std, so error messages refer to the lower level.

like image 200
Shepmaster Avatar answered Sep 19 '22 17:09

Shepmaster