position_elem
from SliceExt
.
Would it be possible to get a more specific error message about what unstable element is being used?
Let us take the latest IntoIterator changes.
let vs = vec![1, 2, 3, 4];
for v in vs {
println!("{}", v);
}
gives
main.rs:4:5: 7:2 warning: use of unstable library feature 'core'
main.rs:4 for v in vs {
main.rs:5 println!("{}", v);
main.rs:6 }
main.rs:7 }
main.rs:4:5: 7:2 help: add #![feature(core)] to the crate attributes to silence this warning
main.rs:4 for v in vs {
main.rs:5 println!("{}", v);
main.rs:6 }
main.rs:7 }
From this it is very hard to find out what is actually being used.
It would be very convenient if it mentioned what is the cause of this.
Usually it's much more clear than that. In this case, I think the problem is that the referenced item (IntoIterator
) is only implicitly in the desugared version of the code.
More commonly you're just calling some unstable method, in which case the error span is more precise.
rust-url uses:
- In the
core
feature:into_owned
,Cow
,Error
trait,from_str_radix
- In the
collections
feature:char_at
,char_range_at
,position_elem
- In the
std_misc
feature:is_ascii
,into_ascii_lowercase
,to_ascii_lowercase
I also have a lot of as_slice
and some range
, but these have a replacement. Maybe they should be deprecated rather than unstable now?
In my project that deals a lot with ffi, I use:
- std::slice::from_raw_buf
- std::ffi::c_str_to_bytes
- std::ffi::CString
- std::marker::ContravariantLifetime
- std::string::String::from_str
- could be replaced with to_string, but it's apparently more performant
- std::ptr::PtrExt::as_ref
- it's a really nice convenience, but I could live without it
- std::vec::Vec::map_in_place
- doubt it'll be stabilized and I could transmute instead
Note though that this particular warning is very easy to hit and very confusing. I was just surprised by it in the playpen and it took me a little while to pare my program down and then find this thread and @wahrsagevogel's post about the same issue. It's pretty jarring to get a confusing warning from pretty much the simplest possible post-hello-world program.
This thread seems like a rather adhoc approach to this, and I'm not sure its useful.
Wouldn't it be significantly easier and more meaningful to grep crates.io for #[feature] tags, and look at what people are actually using?
The 'give feedback' can then be; publish your crate on crates.io and make sure it compiles.
(Obviously you'd have to filter out old crates which are broken, but that's something crates.io needs to do anyway)
(or search github for rust projects and do the same)
This approach will be workable in the long run, once we've split up the feature names at a finer grain. Right now, though, knowing that a crate uses "core" or "collections" isn't so informative -- it's helpful to know the specific APIs, and the use cases motivating them.
dbus-rs uses:
from core: IntoCow, Str, Error
from alloc: Weak
from std_misc: CString, c_str_to_bytes
from libc: mostly basic stuff like c_void, c_int, c_char, etc
Not all code that uses unstable APIs is on crates.io. Not all use of current use of rust is open source.
I also am depending a lot on the unstable unboxed_closures feature (using the Fn* traits w/ angle bracket notation).
As far as I know, the Fn
traits can't be stabilized yet because the final syntax will likely use variadic generics.
I'm using a few unstable APIs from collections
for &str
s in a lexer I'm writing:
char_at
contains_char
find_str
The warning messages imply that these will either be renamed or a more generic version will be offered, so I'm not too worried.
collections
:
String::from_str
std_msc
:
as_raw_fd
CString
c_str_to_bytes
core
:
range
libc
:
c_void, c_int, etc...
consts::os::extra::O_NONBLOCK
consts::os::posix01::F_SETFL
The ability to get a raw fd and set flags so that system calls can be used to read/write to sockets is especially useful if the core io lib wants to be used, and achieve non-blocking io on *nix systems.
I'm working on a Rust plugin for NetBeans that embeds the Rust compiler in Java via JNI. The main things that are important to me are:
-
libc
/std_misc
features: FFI stuff for fields on structs that pass between Java and Rust-
c_int
,c_char
,CString::from_slice
,ffi::c_str_to_bytes
-
-
unwind::try
(fromstd_misc
)- because the lexer and parser both panic when they come across
fatal
errors, which will bring down the JVM. Instead of returning values from the parser or lexer, I pass them back to Java in a callback in thetry
block. I think I wouldn't need this API if the compiler API returned errors instead of panicking.
- because the lexer and parser both panic when they come across
-
rustc_private
feature. I use the compiler, parser and lexer APIs in the following crates:-
rustc
(mostly to create a session before compiling) -
rustc_driver
(to run about half of what rustc does, in order to get compile errors for highlighting) -
rustc_trans
(only for one line: there was a slight limitation with therustc_driver
API that made me dig deeper) -
sytnax
(for the lexer, parser and visitor APIs, to get parse errors and for syntax highlighting)
-
range
is replaced by the (..)
notation, e.g. range(0, 5)
is now (0..5)
.
std::num::Int::{zero, one, count_ones}
These are useful for generic integer algorithms. It looks like all of the generic casting functions/methods are still unstable.
Could you tell me about your use of allocate/deallocate, and whether you could work around it? These are going to be tricky to stabilize for 1.0
You can see the full code for yourself, but the general idea is that I have an interned string pool. The pool itself maintains a list of Chunks
, which are just areas of bytes where I stick a bunch of strings. It's entirely possible that I could just replace the backing memory with a Vec<u8>
with a capacity. It would be a bit slower as I think the chunk would need to be initialized to zero though, and the whole point was to eke out maximum speed.
Vec
s don't need to be initialized to 0, you could always do:
let mut v: Vec<u8> = Vec::with_capacity(cap);
unsafe { v.set_len(cap); }
And then you've got a buffer without having to initialize its contents.