rust-lang/rust — pull request #19612 by japaric (2014-12-07 05:59:48+00:00)
Title: [WIP] `str` is dead, long live `str([u8])`!

This PR removes the built-in/primitive `str` type from the compiler, and replaces it with a library type: `str([u8])`. This new type is defined in the `core::str` module, and re-exported in the `collections::str` and `std::str` modules.

[breaking-change]s

For most of people:

- `str` is now a struct imported as part of the `std` prelude, this means that importing the `std::str` module or using `str` as a variable name now is a name clash, and will result in a compile error.

- The `StrPrelude` trait has been removed, and all the methods defined in it are now inherent methods of the new `str` type. This will break code that was explicitly using the `StrPrelude` trait.

For `#![non_std]` users:

- If you are *not* using the `core` crate then you need to define the `str` type and mark it with the `"str"` lang item:

``` rust
#[lang = "str"]
struct str([u8]);
```

- The `format_args!` and `panic!` macros now use `std::str::str` instead of just `str` in their expansion, to use these macros you'll need to use the "`std` module trick":

``` rust
#[doc(hidden)]
pub mod std {
pub use core::cmp: // for `#[deriving(PartialOrd)]`
pub use core::str; // for `panic!`, `format_args!`
}
```

Closes #19036

---

This passes `make check` as it is, but I broke the `run-pass/unsized3` test (it triggers an LLVM assertion) and I'm currently investigating how to fix it.

@nikomatsakis re: compiler. I removed the `sty::ty_str` variant and replaced it with the following check: `ty_struct(def_id, _) if ty::is_str(cx, def_id)` in most `match` expressions. But, I'm sure that I can simplify the logic (i.e. remove that match arm) in several parts of the compiler, which I'd like to do before landing this.

@aturon re: library. One annoying thing after this change is that the `str` type/struct now collides with the `std::str` module (when imported). As a "fix", instead of directly importing the module, I now import it under the `str_` name (`use std::str as str_`). From what I've seen that the main reason for importing that module is to use its free functions (e.g. `str::from_utf8`), so I'm wondering if we should convert all those free functions into inherent methods of `str`, that way `str::from_utf8` would work without needing to import `std::str`, and no collision would occur. Thoughts?