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 typeT
[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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With