This patch transforms functions of the form
```
fn f<Generic: AsRef<Concrete>>(arg: Generic) {
let arg: &Concrete = arg.as_ref();
// Code using arg
}
```
to the next form:
```
#[inline]
fn f<Generic: AsRef<Concrete>>(arg: Generic) {
fn f_inner(arg: &Concrete) {
// Code using arg
}
f_inner(arg.as_ref());
}
```
Therefore, most of the code is concrete and not duplicated during monomorphisation (unless inlined)
and only the tiny bit of conversion code is duplicated. This method was mentioned by @aturon in the
Conversion Traits RFC (https://github.com/rust-lang/rfcs/blame/master/text/0529-conversion-traits.md#L249) and similar techniques are not uncommon in C++ template libraries.
This patch goes to the extremes and applies the transformation even to smaller functions<sup>1</sup>
for purity of the experiment. *Some of them can be rolled back* if considered too ridiculous.
<sup>1</sup> However who knows how small are these functions are after inlining and everything.
The functions in question are mostly `fs`/`os` functions and not used especially often with variety
of argument types, so the code size reduction is rather small (but consistent). Here are the sizes
of stage2 artifacts before and after the patch:
https://gist.github.com/petrochenkov/e76a6b280f382da13c5dhttps://gist.github.com/petrochenkov/6cc28727d5256dbdfed0
Note:
All the `inner` functions are concrete and unavailable for cross-crate inlining, some of them may
need `#[inline]` annotations in the future.
r? @aturon
Conventionally in C `*mut T` is a transfer of ownership where `*const T` is a
loan, so `*mut T` is likely the more appropriate return type for these
functions. Additionally, this more closely mirrors the APIs on `Box` for this
sort of functionality.
cc #27769
This commit renames the `CString::{into_ptr, from_ptr}` methods to `into_raw`
and `from_raw` to mirror the corresponding methods on `Box` and the naming of
"raw" for `from_raw_parts` on slices and vectors.
cc #27769
This commit removes all unstable and deprecated functions in the standard
library. A release was recently cut (1.3) which makes this a good time for some
spring cleaning of the deprecated functions.
The replacements are functions that usually use a single `mem::transmute` in
their body and restrict input and output via more concrete types than `T` and
`U`. Worth noting are the `transmute` functions for slices and the `from_utf8*`
family for mutable slices. Additionally, `mem::transmute` was often used for
casting raw pointers, when you can already cast raw pointers just fine with
`as`.
This commit is an implementation of [RFC 1184][rfc] which tweaks the behavior of
the `#![no_std]` attribute and adds a new `#![no_core]` attribute. The
`#![no_std]` attribute now injects `extern crate core` at the top of the crate
as well as the libcore prelude into all modules (in the same manner as the
standard library's prelude). The `#![no_core]` attribute disables both std and
core injection.
[rfc]: https://github.com/rust-lang/rfcs/pull/1184
Faithfully represent the contents of the CString and CStr in their Debug
impl, by treating them as byte strings with our default escaping to
ascii representation.
Add impl Debug for Cstr.
Fixes#26964.
This allows CString and CStr to be used with the Cow type,
which is extremely useful when interfacing with C libraries
that make extensive use of C-style strings.
This was motivated by http://www.evanmiller.org/a-taste-of-rust.html.
A common problem when working with FFI right now is converting from raw
C strings into `&str` or `String`. Right now you're required to say
something like
let cstr = unsafe { CStr::from_ptr(ptr) };
let result = str::from_utf8(cstr.to_bytes());
This is slightly awkward, and is not particularly intuitive for people
who haven't used the ffi module before. We can do a bit better by
providing some convenience methods on CStr:
fn to_str(&self) -> Result<&str, str::Utf8Error>
fn to_string_lossy(&self) -> Cow<str>
This will make it immediately apparent to new users of CStr how to get a
string from a raw C string, so they can say:
let s = unsafe { CStr::from_ptr(ptr).to_string_lossy() };
A common problem when working with FFI right now is converting from raw
C strings into `&str` or `String`. Right now you're required to say
something like
let cstr = unsafe { CStr::from_ptr(ptr) };
let result = str::from_utf8(cstr.to_bytes());
This is slightly awkward, and is not particularly intuitive for people
who haven't used the ffi module before. We can do a bit better by
providing some convenience methods on CStr:
fn to_str(&self) -> Result<&str, str::Utf8Error>
fn to_string_lossy(&self) -> Cow<str>
This will make it immediately apparent to new users of CStr how to get a
string from a raw C string, so they can say:
let s = unsafe { CStr::from_ptr(ptr).to_string_lossy() };
It looks like `from_vec` was subsumed by new at some point,
but the documentation still refers to it as `from_vec`.
This updates the documentation for `from_vec_unchecked`
so that it properly says that it's the unchecked version of `new`.
Also, from_vec_unchecked requires a actual Vec<u8> while
new can take anything that is Into<Vec<u8>>, so I also
mention that in the documentation.
Since this is documentation:
r? @steveklabnik
It looks like `from_vec` was subsumed by new at some point,
but the documentation still refers to it as `from_vec`.
This updates the documentation for `from_vec_unchecked`
so that it properly says that it's the unchecked version of `new`.
Also, from_vec_unchecked requires a actual Vec<u8> while
new can take anything that is Into<Vec<u8>>, so I also
mention that in the documentation.
This commit stabilizes a few remaining bits of the `io::Error` type:
* The `Error::new` method is now stable. The last `detail` parameter was removed
and the second `desc` parameter was generalized to `E: Into<Box<Error>>` to
allow creating an I/O error from any form of error. Currently there is no form
of downcasting, but this will be added in time.
* An implementation of `From<&str> for Box<Error>` was added to liballoc to
allow construction of errors from raw strings.
* The `Error::raw_os_error` method was stabilized as-is.
* Trait impls for `Clone`, `Eq`, and `PartialEq` were removed from `Error` as it
is not possible to use them with trait objects.
This is a breaking change due to the modification of the `new` method as well as
the removal of the trait implementations for the `Error` type.
[breaking-change]
This commit cleans out a large amount of deprecated APIs from the standard
library and some of the facade crates as well, updating all users in the
compiler and in tests as it goes along.
* Marks `#[stable]` the contents of the `std::convert` module.
* Added methods `PathBuf::as_path`, `OsString::as_os_str`,
`String::as_str`, `Vec::{as_slice, as_mut_slice}`.
* Deprecates `OsStr::from_str` in favor of a new, stable, and more
general `OsStr::new`.
* Adds unstable methods `OsString::from_bytes` and `OsStr::{to_bytes,
to_cstring}` for ergonomic FFI usage.
[breaking-change]
This removes the FromError trait, since it can now be expressed using
the new convert::Into trait. All implementations of FromError<E> where
changed to From<E>, and `try!` was changed to use From::from instead.
Because this removes FromError, it is a breaking change, but fixing it
simply requires changing the words `FromError` to `From`, and
`from_error` to `from`.
[breaking-change]
This commit revises `path` and `os_str` to use blanket impls for `From`
on reference types. This both cuts down on the number of required impls,
and means that you can pass through e.g. `T: AsRef<OsStr>` to
`PathBuf::from` without an intermediate call to `as_ref`.
It also makes a FIXME note for later generalizing the blanket impls for
`AsRef` and `AsMut` to use `Deref`/`DerefMut`, once it is possible to do
so.
This is a [breaking-change]. When indexing a generic map (hashmap, etc) using the `[]` operator, it is now necessary to borrow explicitly, so change `map[key]` to `map[&key]` (consistent with the `get` routine). However, indexing of string-valued maps with constant strings can now be written `map["abc"]`.
r? @japaric
cc @aturon @Gankro
This commit:
* Introduces `std::convert`, providing an implementation of
RFC 529.
* Deprecates the `AsPath`, `AsOsStr`, and `IntoBytes` traits, all
in favor of the corresponding generic conversion traits.
Consequently, various IO APIs now take `AsRef<Path>` rather than
`AsPath`, and so on. Since the types provided by `std` implement both
traits, this should cause relatively little breakage.
* Deprecates many `from_foo` constructors in favor of `from`.
* Changes `PathBuf::new` to take no argument (creating an empty buffer,
as per convention). The previous behavior is now available as
`PathBuf::from`.
* De-stabilizes `IntoCow`. It's not clear whether we need this separate trait.
Closes#22751Closes#14433
[breaking-change]