CodeMap.span_to_* perform a lookup of a BytePos(sp.hi), which lands into the next filemap if the last byte of range denoted by Span is also the last byte of the filemap, which results in ICEs or incorrect error reports.
Example:
````
pub fn main() {
let mut num = 3;
let refe = &mut num;
*refe = 5;
println!("{}", num);
}````
(note the empty line in the beginning and the absence of newline at the end)
The above would have caused ICE when trying to report where "refe" borrow ends.
The above without an empty line in the beginning would have reported borrow end to be the first line.
Most probably, this is also responsible for (at least some occurrences of) issue #8256.
The issue is fixed by always adding a newline at the end of non-empty filemaps in case there isn't a new line there already.
Formatting via reflection has been a little questionable for some time now, and
it's a little unfortunate that one of the standard macros will silently use
reflection when you weren't expecting it. This adds small bits of code bloat to
libraries, as well as not always being necessary. In light of this information,
this commit switches assert_eq!() to using {} in the error message instead of
{:?}.
In updating existing code, there were a few error cases that I encountered:
* It's impossible to define Show for [T, ..N]. I think DST will alleviate this
because we can define Show for [T].
* A few types here and there just needed a #[deriving(Show)]
* Type parameters needed a Show bound, I often moved this to `assert!(a == b)`
* `Path` doesn't implement `Show`, so assert_eq!() cannot be used on two paths.
I don't think this is much of a regression though because {:?} on paths looks
awful (it's a byte array).
Concretely speaking, this shaved 10K off a 656K binary. Not a lot, but sometime
significant for smaller binaries.
Make bytepos_to_charpos relative to the start of the filemap rather than its previous behaviour which was to be realtive to the start of the codemap, but ignoring multi-byte chars in earlier filemaps. Rename to bytepos_to_file_charpos. Add tests for multi-byte chars.
This patch series does a couple things:
* replaces manual `Hash` implementations with `#[deriving(Hash)]`
* adds `Hash` back to `std::prelude`
* minor cleanup of whitespace and variable names.
They are still are not completely correct, since it does not handle
graphemes at all, just codepoints, but at least it handles the common
case correctly.
The calculation was previously very wrong (rather than just a little bit
wrong): it wasn't accounting for the fact that every character is 1
byte, and so multibyte characters were pretending to be zero width.
cc #8706
- `extra::json` didn't make the cut, because of `extra::json` required
dep on `extra::TreeMap`. If/when `extra::TreeMap` moves out of `extra`,
then `extra::json` could move into `serialize`
- `libextra`, `libsyntax` and `librustc` depend on the newly created
`libserialize`
- The extensions to various `extra` types like `DList`, `RingBuf`, `TreeMap`
and `TreeSet` for `Encodable`/`Decodable` were moved into the respective
modules in `extra`
- There is some trickery, evident in `src/libextra/lib.rs` where a stub
of `extra::serialize` is set up (in `src/libextra/serialize.rs`) for
use in the stage0 build, where the snapshot rustc is still making
deriving for `Encodable` and `Decodable` point at extra. Big props to
@huonw for help working out the re-export solution for this
extra: inline extra::serialize stub
fix stuff clobbered in rebase + don't reexport serialize::serialize
no more globs in libserialize
syntax: fix import of libserialize traits
librustc: fix bad imports in encoder/decoder
add serialize dep to librustdoc
fix failing run-pass tests w/ serialize dep
adjust uuid dep
more rebase de-clobbering for libserialize
fixing tests, pushing libextra dep into cfg(test)
fix doc code in extra::json
adjust index.md links to serialize and uuid library
A mutable and immutable borrow place some restrictions on what you can
with the variable until the borrow ends. This commit attempts to convey
to the user what those restrictions are. Also, if the original borrow is
a mutable borrow, the error message has been changed (more specifically,
i. "cannot borrow `x` as immutable because it is also borrowed as
mutable" and ii. "cannot borrow `x` as mutable more than once" have
been changed to "cannot borrow `x` because it is already borrowed as
mutable").
In addition, this adds a (custom) span note to communicate where the
original borrow ends.
```rust
fn main() {
match true {
true => {
let mut x = 1;
let y = &x;
let z = &mut x;
}
false => ()
}
}
test.rs:6:21: 6:27 error: cannot borrow `x` as mutable because it is already borrowed as immutable
test.rs:6 let z = &mut x;
^~~~~~
test.rs:5:21: 5:23 note: previous borrow of `x` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `x` until the borrow ends
test.rs:5 let y = &x;
^~
test.rs:7:10: 7:10 note: previous borrow ends here
test.rs:3 true => {
test.rs:4 let mut x = 1;
test.rs:5 let y = &x;
test.rs:6 let z = &mut x;
test.rs:7 }
^
```
```rust
fn foo3(t0: &mut &mut int) {
let t1 = &mut *t0;
let p: &int = &**t0;
}
fn main() {}
test.rs:3:19: 3:24 error: cannot borrow `**t0` because it is already borrowed as mutable
test.rs:3 let p: &int = &**t0;
^~~~~
test.rs:2:14: 2:22 note: previous borrow of `**t0` as mutable occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `**t0` until the borrow ends
test.rs:2 let t1 = &mut *t0;
^~~~~~~~
test.rs:4:2: 4:2 note: previous borrow ends here
test.rs:1 fn foo3(t0: &mut &mut int) {
test.rs:2 let t1 = &mut *t0;
test.rs:3 let p: &int = &**t0;
test.rs:4 }
^
```
For the "previous borrow ends here" note, if the span is too long (has too many lines), then only the first and last lines are printed, and the middle is replaced with dot dot dot:
```rust
fn foo3(t0: &mut &mut int) {
let t1 = &mut *t0;
let p: &int = &**t0;
}
fn main() {}
test.rs:3:19: 3:24 error: cannot borrow `**t0` because it is already borrowed as mutable
test.rs:3 let p: &int = &**t0;
^~~~~
test.rs:2:14: 2:22 note: previous borrow of `**t0` as mutable occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `**t0` until the borrow ends
test.rs:2 let t1 = &mut *t0;
^~~~~~~~
test.rs:7:2: 7:2 note: previous borrow ends here
test.rs:1 fn foo3(t0: &mut &mut int) {
...
test.rs:7 }
^
```
(Sidenote: the `span_end_note` currently also has issue #11715)
A mutable and immutable borrow place some restrictions on what you can
with the variable until the borrow ends. This commit attempts to convey
to the user what those restrictions are. Also, if the original borrow is
a mutable borrow, the error message has been changed (more specifically,
i. "cannot borrow `x` as immutable because it is also borrowed as
mutable" and ii. "cannot borrow `x` as mutable more than once" have
been changed to "cannot borrow `x` because it is already borrowed as
mutable").
In addition, this adds a (custom) span note to communicate where the
original borrow ends.
When --dep-info is given, rustc will write out a `$input_base.d` file in the
output directory that contains Makefile compatible dependency information for
use with tools like make and ninja.
I removed the `static-method-test.rs` test because it was heavily based
on `BaseIter` and there are plenty of other more complex uses of static
methods anyway.
This almost removes the StringRef wrapper, since all strings are
Equiv-alent now. Removes a lot of `/* bad */ copy *`'s, and converts
several things to be &'static str (the lint table and the intrinsics
table).
There are many instances of .to_managed(), unfortunately.
Replace all instances of #[auto_*code] with the appropriate #[deriving] attribute
and remove the majority of the actual code, leaving stubs to refer the user to
the new syntax.
fail!() used to require owned strings but can handle static strings
now. Also, it can pass its arguments to fmt!() on its own, no need for
the caller to call fmt!() itself.
Adds an assert_eq! macro that asserts that its two arguments are equal. Error messages can therefore be somewhat more informative than a simple assert, because the error message includes "expected" and "given" values.
For bootstrapping purposes, this commit does not remove all uses of
the keyword "pure" -- doing so would cause the compiler to no longer
bootstrap due to some syntax extensions ("deriving" in particular).
Instead, it makes the compiler ignore "pure". Post-snapshot, we can
remove "pure" from the language.
There are quite a few (~100) borrow check errors that were essentially
all the result of mutable fields or partial borrows of `@mut`. Per
discussions with Niko I think we want to allow partial borrows of
`@mut` but detect obvious footguns. We should also improve the error
message when `@mut` is erroneously reborrowed.
Before this change, encoding an object containing a codemap::span
using the JSON encodeng produced invalid JSON, for instance:
[{"span":,"global":false,"idents":["abc"]}]
Since the decoder for codemap::span's ignores its argument, I
conjecture that this will not damage decoding, and should improve
it for many decoders.
r?
Apply deriving_eq to the data structures in ast.rs, and get rid of the custom definitions of eq that were everywhere. resulting ast.rs is about 400 lines shorter.
Also: add a few test cases and a bunch of comments.
Also: change ast_ty_to_ty_cache to use node ids rather than ast::ty's. I believe this was a suggestion related to my changes, and it appears to pass all tests.
Also: tiny doc fix, remove references to crate keywords.
"Dual impls" are impls that are both type implementations and trait
implementations. They can lead to ambiguity and so this patch removes them
from the language.
This also enforces coherence rules. Without this patch, records can implement
traits not defined in the current crate. This patch fixes this, and updates
all of rustc to adhere to the new enforcement. Most of this patch is fixing
rustc to obey the coherence rules, which involves converting a bunch of records
to structs.