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

2019-06-25 13:29发布

问题:

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)

回答1:

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.



标签: rust