The regex library was largely used for non-critical aspects of the compiler and
various external tooling. The library at this point is duplicated with its
out-of-tree counterpart and as such imposes a bit of a maintenance overhead as
well as compile time hit for the compiler itself.
The last major user of the regex library is the libtest library, using regexes
for filters when running tests. This removal means that the filtering has gone
back to substring matching rather than using regexes.
In accordance with [collections reform part 2][rfc] this macro has been moved to
an external [bitflags crate][crate] which is [available though
crates.io][cratesio]. Inside the standard distribution the macro has been moved
to a crate called `rustc_bitflags` for current users to continue using.
[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0509-collections-reform-part-2.md
[crate]: https://github.com/rust-lang/bitflags
[cratesio]: http://crates.io/crates/bitflags
The major user of `bitflags!` in terms of a public-facing possibly-stable API
today is the `FilePermissions` structure inside of `std::io`. This user,
however, will likely no longer use `bitflags!` after I/O reform has landed. To
prevent breaking APIs today, this structure remains as-is.
Current users of the `bitflags!` macro should add this to their `Cargo.toml`:
bitflags = "0.1"
and this to their crate root:
#[macro_use] extern crate bitflags;
Due to the removal of a public macro, this is a:
[breaking-change]
#### Updated 1/12/2014
I updated the multi-line testcase to current but didn't modify the others. The spew code was broke by the `matches!` macro no longer working and I'm not interested in fixing the testcase.
I additionally added one testcase below.
Errors will in general look similar to below if the error is either `mismatched types` or a few other types. The rest are ignored.
---
#### Extra testcase:
```rust
pub trait Foo {
type A;
fn boo(&self) -> <Self as Foo>::A;
}
struct Bar;
impl Foo for i32 {
type A = u32;
fn boo(&self) -> u32 {
42
}
}
fn foo1<I: Foo<A=Bar>>(x: I) {
let _: Bar = x.boo();
}
fn foo2<I: Foo>(x: I) {
let _: Bar = x.boo();
}
pub fn baz(x: &Foo<A=Bar>) {
let _: Bar = x.boo();
}
pub fn main() {
let a = 42i32;
foo1(a);
baz(&a);
}
```
#### Multi-line output:
```cmd
$ ./rustc test3.rs
test3.rs:20:18: 20:25 error: mismatched types:
expected `Bar`,
found `<I as Foo>::A`
(expected struct `Bar`,
found associated type)
test3.rs:20 let _: Bar = x.boo();
^~~~~~~
test3.rs:31:5: 31:9 error: type mismatch resolving `<i32 as Foo>::A == Bar`:
expected u32,
found struct `Bar`
test3.rs:31 foo1(a);
^~~~
test3.rs:31:5: 31:9 note: required by `foo1`
test3.rs:31 foo1(a);
^~~~
test3.rs:32:9: 32:11 error: type mismatch resolving `<i32 as Foo>::A == Bar`:
expected u32,
found struct `Bar`
test3.rs:32 baz(&a);
^~
test3.rs:32:9: 32:11 note: required for the cast to the object type `Foo`
test3.rs:32 baz(&a);
^~
error: aborting due to 3 previous errors
```
---
This is a continuation of #19203 which I apparently broke by force pushing after it was closed. I'm attempting to add multi-line errors where they are largely beneficial - to help differentiate different types in compiler messages. As before, this is still a simple fix.
#### Testcase:
```rust
struct S;
fn test() -> Option<i32> {
let s: S;
s
}
fn test2() -> Option<i32> {
Ok(7) // Should be Some(7)
}
impl Iterator for S {
type Item = i32;
fn next(&mut self) -> Result<i32, i32> { Ok(7) }
}
fn main(){
test();
test2();
}
```
---
#### Single-line playpen errors:
```cmd
<anon>:6:5: 6:6 error: mismatched types: expected `core::option::Option<int>`, found `S` (expected enum core::option::Option, found struct S)
<anon>:6 s
^
<anon>:10:5: 10:10 error: mismatched types: expected `core::option::Option<int>`, found `core::result::Result<_, _>` (expected enum core::option::Option, found enum core::result::Result)
<anon>:10 Ok(7) // Should be Some(7)
^~~~~
<anon>:14:5: 14:55 error: method `next` has an incompatible type for trait: expected enum core::option::Option, found enum core::result::Result [E0053]
<anon>:14 fn next(&mut self) -> Result<uint, uint> { Ok(7) }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 3 previous errors
playpen: application terminated with error code 101
```
---
#### Multi-line errors:
```cmd
$ ./rustc test.rs
test.rs:6:5: 6:6 error: mismatched types:
expected `core::option::Option<i32>`,
found `S`
(expected enum `core::option::Option`,
found struct `S`)
test.rs:6 s
^
test.rs:10:5: 10:10 error: mismatched types:
expected `core::option::Option<i32>`,
found `core::result::Result<_, _>`
(expected enum `core::option::Option`,
found enum `core::result::Result`)
test.rs:10 Ok(7) // Should be Some(7)
^~~~~
test.rs:15:5: 15:53 error: method `next` has an incompatible type for trait: expected enum `core::option::Option`, found enum `core::result::Result` [E0053]
test.rs:15 fn next(&mut self) -> Result<i32, i32> { Ok(7) }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 3 previous errors
```
---
#### Positive notes
* Vim worked fine with it: https://github.com/rust-lang/rust/pull/19203#issuecomment-66861668
* `make check` didn't find any errors
* Fixed *backtick* placement suggested by @p1start at https://github.com/rust-lang/rust/pull/19203#issuecomment-64062052
#### Negative notes
* Didn't check Emacs support but also wasn't provided a testcase...
* Needs to be tested with macro errors but I don't have a good testcase yet
* I would like to move the `E[0053]` earlier (see https://github.com/rust-lang/rust/issues/19464#issuecomment-65334301) but I don't know how
* It might be better to indent the types slightly like so (but I don't know how):
```cmd
test.rs:6:5: 6:6 error: mismatched types:
expected `core::option::Option<int>`,
found `S`
(expected enum `core::option::Option`,
found struct `S`)
test.rs:6 s
```
* Deep whitespace indentation may be a bad idea because early wrapping will cause misalignment between lines
#### Other
* I thought that compiler flags or something else (environment variables maybe) might be required because of comments against it but now that seems too much of a burden for users and for too little gain.
* There was concern that it will make large quantities of errors difficult to distinguish but I don't find that an issue. They both look awful and multi-line errors makes the types easier to understand.
---
#### Single lined spew:
```cmd
$ rustc test2.rs
test2.rs:161:9: 170:10 error: method `next` has an incompatible type for trait: expected enum core::option::Option, found enum core::result::Result [E0053]
test2.rs:161 fn next(&mut self) -> Result<&'a str, int> {
test2.rs:162 self.curr = self.next;
test2.rs:163
test2.rs:164 if let (Some(open), Some(close)) = Parens::find_parens(self.all, self.next) {
test2.rs:165 self.next = if self.all.char_at(self.next) == '(' { close }
test2.rs:166 else { open }
...
test2.rs:164:21: 164:31 error: mismatched types: expected `core::result::Result<uint, int>`, found `core::option::Option<_>` (expected enum core::result::Result, found enum core::option::Option)
test2.rs:164 if let (Some(open), Some(close)) = Parens::find_parens(self.all, self.next) {
^~~~~~~~~~
test2.rs:164:33: 164:44 error: mismatched types: expected `core::result::Result<uint, int>`, found `core::option::Option<_>` (expected enum core::result::Result, found enum core::option::Option)
test2.rs:164 if let (Some(open), Some(close)) = Parens::find_parens(self.all, self.next) {
^~~~~~~~~~~
test2.rs:169:40: 169:76 error: mismatched types: expected `core::result::Result<&'a str, int>`, found `core::option::Option<&str>` (expected enum core::result::Result, found enum core::option::Option)
test2.rs:169 if self.curr != self.len { Some(self.all[self.curr..self.next]) } else { None }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test2.rs:169:86: 169:90 error: mismatched types: expected `core::result::Result<&'a str, int>`, found `core::option::Option<_>` (expected enum core::result::Result, found enum core::option::Option)
test2.rs:169 if self.curr != self.len { Some(self.all[self.curr..self.next]) } else { None }
^~~~
test2.rs:205:14: 205:18 error: mismatched types: expected `core::result::Result<uint, int>`, found `core::option::Option<uint>` (expected enum core::result::Result, found enum core::option::Option)
test2.rs:205 (open, close)
^~~~
test2.rs:205:20: 205:25 error: mismatched types: expected `core::result::Result<uint, int>`, found `core::option::Option<uint>` (expected enum core::result::Result, found enum core::option::Option)
test2.rs:205 (open, close)
^~~~~
test2.rs:210:21: 210:31 error: mismatched types: expected `core::result::Result<uint, int>`, found `core::option::Option<_>` (expected enum core::result::Result, found enum core::option::Option)
test2.rs:210 if let (Some(open), _) = Parens::find_parens(self.all, 0) {
^~~~~~~~~~
test2.rs:210:13: 212:28 error: mismatched types: expected `core::option::Option<&'a int>`, found `core::option::Option<&str>` (expected int, found str)
test2.rs:210 if let (Some(open), _) = Parens::find_parens(self.all, 0) {
test2.rs:211 Some(self.all[0..open])
test2.rs:212 } else { None }
test2.rs:299:48: 299:58 error: mismatched types: expected `Box<translate::Entity>`, found `collections::vec::Vec<_>` (expected box, found struct collections::vec::Vec)
test2.rs:299 pub fn new() -> Entity { Entity::Group(Vec::new()) }
^~~~~~~~~~
test2.rs:359:51: 359:58 error: type `&mut Box<translate::Entity>` does not implement any method in scope named `push`
test2.rs:359 Entity::Group(ref mut vec) => vec.push(e),
^~~~~~~
test2.rs:366:51: 366:85 error: type `&mut Box<translate::Entity>` does not implement any method in scope named `push`
test2.rs:366 Entity::Group(ref mut vec) => vec.push(Entity::Inner(s.to_string())),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 12 previous errors
```
---
#### Multi-line spew:
```cmd
$ ./rustc test2.rs
test2.rs:161:9: 170:10 error: method `next` has an incompatible type for trait:
expected enum `core::option::Option`,
found enum `core::result::Result` [E0053]
test2.rs:161 fn next(&mut self) -> Result<&'a str, int> {
test2.rs:162 self.curr = self.next;
test2.rs:163
test2.rs:164 if let (Some(open), Some(close)) = Parens::find_parens(self.all, self.next) {
test2.rs:165 self.next = if self.all.char_at(self.next) == '(' { close }
test2.rs:166 else { open }
...
test2.rs:164:21: 164:31 error: mismatched types:
expected `core::result::Result<uint, int>`,
found `core::option::Option<_>`
(expected enum `core::result::Result`,
found enum `core::option::Option`)
test2.rs:164 if let (Some(open), Some(close)) = Parens::find_parens(self.all, self.next) {
^~~~~~~~~~
test2.rs:164:33: 164:44 error: mismatched types:
expected `core::result::Result<uint, int>`,
found `core::option::Option<_>`
(expected enum `core::result::Result`,
found enum `core::option::Option`)
test2.rs:164 if let (Some(open), Some(close)) = Parens::find_parens(self.all, self.next) {
^~~~~~~~~~~
test2.rs:169:40: 169:76 error: mismatched types:
expected `core::result::Result<&'a str, int>`,
found `core::option::Option<&str>`
(expected enum `core::result::Result`,
found enum `core::option::Option`)
test2.rs:169 if self.curr != self.len { Some(self.all[self.curr..self.next]) } else { None }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test2.rs:169:86: 169:90 error: mismatched types:
expected `core::result::Result<&'a str, int>`,
found `core::option::Option<_>`
(expected enum `core::result::Result`,
found enum `core::option::Option`)
test2.rs:169 if self.curr != self.len { Some(self.all[self.curr..self.next]) } else { None }
^~~~
test2.rs:205:14: 205:18 error: mismatched types:
expected `core::result::Result<uint, int>`,
found `core::option::Option<uint>`
(expected enum `core::result::Result`,
found enum `core::option::Option`)
test2.rs:205 (open, close)
^~~~
test2.rs:205:20: 205:25 error: mismatched types:
expected `core::result::Result<uint, int>`,
found `core::option::Option<uint>`
(expected enum `core::result::Result`,
found enum `core::option::Option`)
test2.rs:205 (open, close)
^~~~~
test2.rs:210:21: 210:31 error: mismatched types:
expected `core::result::Result<uint, int>`,
found `core::option::Option<_>`
(expected enum `core::result::Result`,
found enum `core::option::Option`)
test2.rs:210 if let (Some(open), _) = Parens::find_parens(self.all, 0) {
^~~~~~~~~~
test2.rs:210:13: 212:28 error: mismatched types:
expected `core::option::Option<&'a int>`,
found `core::option::Option<&str>`
(expected int,
found str)
test2.rs:210 if let (Some(open), _) = Parens::find_parens(self.all, 0) {
test2.rs:211 Some(self.all[0..open])
test2.rs:212 } else { None }
test2.rs:229:57: 229:96 error: the trait `core::ops::Fn<(char,), bool>` is not implemented for the type `|char| -> bool`
test2.rs:229 .map(|s| s.trim_chars(|c: char| c.is_whitespace()))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test2.rs:238:46: 239:75 error: type `core::str::CharSplits<'_, |char| -> bool>` does not implement any method in scope named `filter_map`
test2.rs:238 .filter_map(|s| if !s.is_empty() { Some(s.trim_chars('\'')) }
test2.rs:239 else { None })
test2.rs:237:46: 237:91 error: the trait `core::ops::Fn<(char,), bool>` is not implemented for the type `|char| -> bool`
test2.rs:237 let vec: Vec<&str> = value[].split(|c: char| matches!(c, '(' | ')' | ','))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test2.rs:238:65: 238:77 error: the type of this value must be known in this context
test2.rs:238 .filter_map(|s| if !s.is_empty() { Some(s.trim_chars('\'')) }
^~~~~~~~~~~~
test2.rs:299:48: 299:58 error: mismatched types:
expected `Box<translate::Entity>`,
found `collections::vec::Vec<_>`
(expected box,
found struct `collections::vec::Vec`)
test2.rs:299 pub fn new() -> Entity { Entity::Group(Vec::new()) }
^~~~~~~~~~
test2.rs:321:36: 322:65 error: type `core::str::CharSplits<'_, |char| -> bool>` does not implement any method in scope named `filter_map`
test2.rs:321 .filter_map(|s| if !s.is_empty() { Some(s.trim_chars('\'')) }
test2.rs:322 else { None })
test2.rs:320:36: 320:81 error: the trait `core::ops::Fn<(char,), bool>` is not implemented for the type `|char| -> bool`
test2.rs:320 let vec: Vec<&str> = s.split(|c: char| matches!(c, '(' | ')' | ','))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test2.rs:321:55: 321:67 error: the type of this value must be known in this context
test2.rs:321 .filter_map(|s| if !s.is_empty() { Some(s.trim_chars('\'')) }
^~~~~~~~~~~~
test2.rs:359:51: 359:58 error: type `&mut Box<translate::Entity>` does not implement any method in scope named `push`
test2.rs:359 Entity::Group(ref mut vec) => vec.push(e),
^~~~~~~
test2.rs:366:51: 366:85 error: type `&mut Box<translate::Entity>` does not implement any method in scope named `push`
test2.rs:366 Entity::Group(ref mut vec) => vec.push(Entity::Inner(s.to_string())),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 24 previous errors
```
Closes#18946#19464
cc @P1start @jakub- @tomjakubowski @kballard @chris-morgan
This gets rid of the 'experimental' level, removes the non-staged_api
case (i.e. stability levels for out-of-tree crates), and lets the
staged_api attributes use 'unstable' and 'deprecated' lints.
This makes the transition period to the full feature staging design
a bit nicer.
To avoid using the feauture, change uses of `box <expr>` to
`Box::new(<expr>)` alternative, as noted by the feature gate message.
(Note that box patterns have no analogous trivial replacement, at
least not in general; you need to revise the code to do a partial
match, deref, and then the rest of the match.)
[breaking-change]
This partially implements the feature staging described in the
[release channel RFC][rc]. It does not yet fully conform to the RFC as
written, but does accomplish its goals sufficiently for the 1.0 alpha
release.
It has three primary user-visible effects:
* On the nightly channel, use of unstable APIs generates a warning.
* On the beta channel, use of unstable APIs generates a warning.
* On the beta channel, use of feature gates generates a warning.
Code that does not trigger these warnings is considered 'stable',
modulo pre-1.0 bugs.
Disabling the warnings for unstable APIs continues to be done in the
existing (i.e. old) style, via `#[allow(...)]`, not that specified in
the RFC. I deem this marginally acceptable since any code that must do
this is not using the stable dialect of Rust.
Use of feature gates is itself gated with the new 'unstable_features'
lint, on nightly set to 'allow', and on beta 'warn'.
The attribute scheme used here corresponds to an older version of the
RFC, with the `#[staged_api]` crate attribute toggling the staging
behavior of the stability attributes, but the user impact is only
in-tree so I'm not concerned about having to make design changes later
(and I may ultimately prefer the scheme here after all, with the
`#[staged_api]` crate attribute).
Since the Rust codebase itself makes use of unstable features the
compiler and build system to a midly elaborate dance to allow it to
bootstrap while disobeying these lints (which would otherwise be
errors because Rust builds with `-D warnings`).
This patch includes one significant hack that causes a
regression. Because the `format_args!` macro emits calls to unstable
APIs it would trigger the lint. I added a hack to the lint to make it
not trigger, but this in turn causes arguments to `println!` not to be
checked for feature gates. I don't presently understand macro
expansion well enough to fix. This is bug #20661.
Closes#16678
[rc]: https://github.com/rust-lang/rfcs/blob/master/text/0507-release-channels.md
This is a [breaking-change]. The new rules require that, for an impl of a trait defined
in some other crate, two conditions must hold:
1. Some type must be local.
2. Every type parameter must appear "under" some local type.
Here are some examples that are legal:
```rust
struct MyStruct<T> { ... }
// Here `T` appears "under' `MyStruct`.
impl<T> Clone for MyStruct<T> { }
// Here `T` appears "under' `MyStruct` as well. Note that it also appears
// elsewhere.
impl<T> Iterator<T> for MyStruct<T> { }
```
Here is an illegal example:
```rust
// Here `U` does not appear "under" `MyStruct` or any other local type.
// We call `U` "uncovered".
impl<T,U> Iterator<U> for MyStruct<T> { }
```
There are a couple of ways to rewrite this last example so that it is
legal:
1. In some cases, the uncovered type parameter (here, `U`) should be converted
into an associated type. This is however a non-local change that requires access
to the original trait. Also, associated types are not fully baked.
2. Add `U` as a type parameter of `MyStruct`:
```rust
struct MyStruct<T,U> { ... }
impl<T,U> Iterator<U> for MyStruct<T,U> { }
```
3. Create a newtype wrapper for `U`
```rust
impl<T,U> Iterator<Wrapper<U>> for MyStruct<T,U> { }
```
Because associated types are not fully baked, which in the case of the
`Hash` trait makes adhering to this rule impossible, you can
temporarily disable this rule in your crate by using
`#![feature(old_orphan_check)]`. Note that the `old_orphan_check`
feature will be removed before 1.0 is released.
This commit completes the deprecation story for the in-tree serialization
library. The compiler will now emit a warning whenever it encounters
`deriving(Encodable)` or `deriving(Decodable)`, and the library itself is now
marked `#[unstable]` for when feature staging is enabled.
All users of serialization can migrate to the `rustc-serialize` crate on
crates.io which provides the exact same interface as the libserialize library
in-tree. The new deriving modes are named `RustcEncodable` and `RustcDecodable`
and require `extern crate "rustc-serialize" as rustc_serialize` at the crate
root in order to expand correctly.
To migrate all crates, add the following to your `Cargo.toml`:
[dependencies]
rustc-serialize = "0.1.1"
And then add the following to your crate root:
extern crate "rustc-serialize" as rustc_serialize;
Finally, rename `Encodable` and `Decodable` deriving modes to `RustcEncodable`
and `RustcDecodable`.
[breaking-change]
This commit completes the deprecation story for the in-tree serialization
library. The compiler will now emit a warning whenever it encounters
`deriving(Encodable)` or `deriving(Decodable)`, and the library itself is now
marked `#[unstable]` for when feature staging is enabled.
All users of serialization can migrate to the `rustc-serialize` crate on
crates.io which provides the exact same interface as the libserialize library
in-tree. The new deriving modes are named `RustcEncodable` and `RustcDecodable`
and require `extern crate "rustc-serialize" as rustc_serialize` at the crate
root in order to expand correctly.
To migrate all crates, add the following to your `Cargo.toml`:
[dependencies]
rustc-serialize = "0.1.1"
And then add the following to your crate root:
extern crate "rustc-serialize" as rustc_serialize;
Finally, rename `Encodable` and `Decodable` deriving modes to `RustcEncodable`
and `RustcDecodable`.
[breaking-change]
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
followed by a semicolon.
This allows code like `vec![1i, 2, 3].len();` to work.
This breaks code that uses macros as statements without putting
semicolons after them, such as:
fn main() {
...
assert!(a == b)
assert!(c == d)
println(...);
}
It also breaks code that uses macros as items without semicolons:
local_data_key!(foo)
fn main() {
println("hello world")
}
Add semicolons to fix this code. Those two examples can be fixed as
follows:
fn main() {
...
assert!(a == b);
assert!(c == d);
println(...);
}
local_data_key!(foo);
fn main() {
println("hello world")
}
RFC #378.
Closes#18635.
[breaking-change]