Noob: diff Cargo v #![feature(rustc_private)]


#1

What is #![feature(rustc_private)] and is there a route to using Cargo to compile the same code?

I just tried to compile the example at http://rustbyexample.com/std_misc/arg/getopts.html
but run into compile error

error: unresolved name `getopts::optflag

I’m in the habit of using Cargo but this one doesn’t compile unless done with rustc.

What is the difference here? As far as I can see getopts is the same as any crate from other https://crates.io


#2

Hi davidpbrown,

I used a demo from getopts GitHub sources and could compile it with Cargo.

https://github.com/rust-lang/getopts/blob/master/src/lib.rs (just read the comments from the beginning of lib.rs)

Also, you can find the same info here: http://doc.rust-lang.org/getopts/getopts/index.html

I’ve created a small cargo project that you can download from my server if you like.

I’m using rust v.1.1.0

http://brakmic.de/download/getopts.zip

Regards,
Harris


#3

Thanks… I’d seen that and it works fine here too. I’m just trying to understand the basics rather than achieve something specific… although I’m putting aside useful tools and not requiring rustc and features, preferred.

I just can’t see the difference in that example, that requires rustc and rustc_private.

I thought it would be something about the missing

use getopts::Options;

but that’s not the error… with that line or not, the same error follows.

Where is this coming from against Cargo of http://rustbyexample.com/std_misc/arg/getopts.html

error: unresolved name `getopts::optflag

Surely that getopts::optflag should be visible?


#4

I did not find any information on “rustc_private”.
I can only speculate about it…maybe some sort of “unstable” feature or “not for use in external APIs”?


#5

but why doesn’t Cargo just work?.. I could perhaps de-construct it but was hoping someone can just see the obvious that I’m missing.


#6

rustc_private is a feature flag, just like any other flag. This feature flag is one that we’re never going to stabilize, though: it’s so that the Rust compiler can use certain libraries, but not expose them to the outside world.

For example, getopts, the original issue from the first post. It is on crates.io here: https://crates.io/crates/getopts it is also in-tree here: https://github.com/rust-lang/rust/tree/master/src/libgetopts You can see the feature flag being turned on here: https://github.com/rust-lang/rust/blob/master/src/libgetopts/lib.rs#L82-L83

By requiring user code to use the external package, we don’t have to worry about updating the compiler every single time we want to update the external package. We can let it lag a bit or diverge, or enhance the external package for use-cases the compiler doesn’t need.


#7

So, the compiler is happy…

I still don’t see why there’s a difference in trying to use the crate.io version via Cargo, in that example above; unless there some issue with Cargo preferring in-tree code in error where that exists?

Must we use rustc and not Cargo where this flag appears?.. Perhaps that’s not a big issue but it’s an oddity I wasn’t expecting.


#8

As I mentioned above, they may be different. The internal version may diverge from the external one.

You should not use the flag at all, and use the external package instead.


#9

With or without that flag, Cargo doesn’t compile… and being a noob I can’t see why.

I’ve used the dependency suggested via https://crates.io/crates/getopts at http://doc.rust-lang.org/getopts/getopts/index.html also tried the crate.io version and a simple

[dependencies]
getopts = “*”


#10

Can you share your code?


#11

:o http://rustbyexample.com/std_misc/arg/getopts.html is now 404

I’ve been playing around but think this is the original below, except that I added one line for:

use getopts::Options;

#![feature(rustc_private)]

extern crate getopts;
use getopts::Options;

use std::env;
use std::io;
use std::io::Write;
use std::process;

static VERSION: &'static str = "1.0.0";

fn main() {
    let args: Vec<String> = env::args().collect();
    let ref program = args[0];

    // Set possible flags.
    // The first argument to `optflag` is the short flag name.
    // The second argument is the long flag name.
    // The third argument is the help text.
    let opts = [
        getopts::optflag("n", "", "do not output the trailing newline"),
        getopts::optflag("h", "help", "display this help and exit"),
        getopts::optflag("v", "version",
                         "output version information and exit"),
    ];

    let matches = match getopts::getopts(&args[1..], &opts) {
        Ok(m) => m,
        Err(f) => {
            println!("{}", f);
            process::exit(1);
            // The exit code is 0 (success) by default.
            // Any exit code other than 0 indicates failure.
        }
    };

    if matches.opt_present("help") {
        //^ We could as well have used the short name: "h"
        println!("echo {} - display a line of text", VERSION);
        println!("");
        println!("Usage:");
        println!(" {} [SHORT-OPTION]... [STRING]...", program);
        println!(" {} LONG-OPTION", program);
        println!("");
        let usage = getopts::usage("Echo the STRING(s) to standard output.",
                                    &opts);
        println!("{}", usage);
        return;
    }

    if matches.opt_present("version") {
        println!("echo version: {}", VERSION);
        return;
    }

    if !matches.free.is_empty() {
        //^ `matches.free` contains all the arguments that are not options.
        let string = matches.free.join(" ");
        println!("{}", string);
    }

    if !matches.opt_present("n") {
        println!("")
    } else {
        let _ = io::stdout().flush();
    }
}

#12

I wonder the reason that example had

#![feature(rustc_private)]

is because the external crate isn’t working and the complier is defaulting to what it knows exists.

It advice above is correct then there’s no good reason to ever use this feature outside of core rust code… and if the compiler is suggesting that error against an extern crate, then there’s something obscuring sight of that crate. Still unclear why in this instance getopts extern crate is not available as the compiler compiles that external crate before looking at the user’s code.

Has me wonder whether all instances of #![feature(rustc_private)] obscure extern crates and then the differences from the external crates is never available.


#13

So, this is the result of said divergance. The getopts crate has undergone further development since we’ve frozen the in-tree one. By removing the feature flag and adding getopts="*" to Cargo.toml, you get a few errors. Resolving them all looks like this: https://github.com/steveklabnik/optexample

You can see the documentation for the getopts crate here: http://doc.rust-lang.org/getopts/getopts/index.html


#14

The reason the example had rustc_private is that Rust By Example doesn’t have support for external crates. So they were showing off the internal version.