Skip to content

Compiler both suggests and forbids the use of the core module #26768

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
dgoldstein0 opened this issue Jul 4, 2015 · 3 comments
Closed

Compiler both suggests and forbids the use of the core module #26768

dgoldstein0 opened this issue Jul 4, 2015 · 3 comments

Comments

@dgoldstein0
Copy link

This is on Rust 1.1 stable.

I'm learning Rust right now, and decided a good way to start off would be to write a linked list. In the process, I decided to add a print_list function that would traverse my linked list and print out it's contents. This would probably be fine had I not made my list generic, but having done that, I started getting compiler errors about T not being core::fmt::Display.

$ cargo run
   Compiling linked_list v0.1.0 (file:///C:/Users/David/Documents/code/rust/link
ed_list)
src\main.rs:56:36: 56:58 error: the trait `core::fmt::Display` is not implemente
d for the type `T` [E0277]
src\main.rs:56                     println!("{}", (*node).borrow().value);
                                                  ^~~~~~~~~~~~~~~~~~~~~~
note: in expansion of format_args!
<std macros>:2:25: 2:56 note: expansion site
<std macros>:1:1: 2:62 note: in expansion of print!
<std macros>:3:1: 3:54 note: expansion site
<std macros>:1:1: 3:58 note: in expansion of println!
src\main.rs:56:21: 56:60 note: expansion site
src\main.rs:56:36: 56:58 note: `T` cannot be formatted with the default formatte
r; try using `:?` instead if you are using a format string
src\main.rs:56                     println!("{}", (*node).borrow().value);
                                                  ^~~~~~~~~~~~~~~~~~~~~~
note: in expansion of format_args!
<std macros>:2:25: 2:56 note: expansion site
<std macros>:1:1: 2:62 note: in expansion of print!
<std macros>:3:1: 3:54 note: expansion site
<std macros>:1:1: 3:58 note: in expansion of println!
src\main.rs:56:21: 56:60 note: expansion site
error: aborting due to previous error
Could not compile `linked_list`.

To learn more, run the command again with --verbose.

So I added the Display trait and imported the core crate, only to be told (after fixing tons of other type errors) "error: use of unstable library feature 'core'". Why did the compiler even suggest I use core, if it wasn't going to allow it? I also find it weird that built in code depends on core, but I myself am not allowed to use it.

Here's my (probably terrible) code, for reference, which can be used to reproduce this bug.

extern crate core;

use core::fmt::Display;
use std::cell::RefCell;
use std::rc::Rc;

struct LinkedList<T: Copy + Display> {
    head: Option<Rc<RefCell<Node<T>>>>,
    tail: Option<Rc<RefCell<Node<T>>>>,
    length: u32,
}

struct Node<T: Copy> {
    next: Option<Rc<RefCell<Node<T>>>>,
    prev: Option<Rc<RefCell<Node<T>>>>,
    value: T,
}

impl<T: Copy> Node<T> {
    fn new(val: &T) -> Node<T> {
        Node::<T> {
            next: None,
            prev: None,
            value: *val,
        }
    }
}

impl<T: Copy + Display> LinkedList<T> {
    fn new() -> LinkedList<T> {
        LinkedList::<T> {
            head: None,
            tail: None,
            length: 0,
        }
    }

    fn append(&mut self, value: &T) {
        let new_node = Rc::new(RefCell::new(Node::<T>::new(value)));

        match self.tail.clone() {
            None => {
                self.head = Some(new_node.clone());
            },
            Some (tail_node) => {
                (*tail_node).borrow_mut().next = Some(new_node.clone());
                (*new_node).borrow_mut().prev = Some(tail_node.clone());
            }
        }
        self.tail = Some(new_node);
        self.length = self.length + 1;
    }

    fn print_list(&self) {
        let mut next_node = self.head.clone();
        loop {
            match next_node {
                Some(node) => {
                    println!("{}", (*node).borrow().value);
                    next_node = (*node).borrow().next.clone();
                },
                None => return,
            }
        }
    }
}

fn main() {
    let mut list = LinkedList::<i32>::new();

    let vals = vec![3, 2, 1, 0];
    for v in &vals {
        list.append(v);
    }

    list.print_list();
    return;
}
@pmarcelll
Copy link
Contributor

It's a known issue, core::fmt::Display is reexport as std::fmt::Display (because core is unstable), but the compiler is not smart enough to suggest the "public" trait. This also happens with private traits.

Related issues:
#23355
#23224
#13065
#26635
#26454
#25358

@steveklabnik
Copy link
Member

yes, as @pmarcelll says, this is a dup.

Why did the compiler even suggest I use core, if it wasn't going to allow it?

Basicaly, re-exported types don't have the information stored with them that they've been re-exported, so they use their non-re-exported name. Fixing this is going to be a fairly big refactoring, from what I've heard.

I also find it weird that built in code depends on core, but I myself am not allowed to use it.

This is because it's not stable yet. If you used a nightly compiler, you'd be allowed to.

Anyway, I'm closing since this is a dup, but you're completely right that it is a big usability issue. Sorry for the confusion :/

@dgoldstein0
Copy link
Author

Thanks for the super quick response, and for the pointer to use it from std - that did the trick for me. Also glad to know the problem is on your radar.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants