This can almost be fully disabled, as it no longer breaks retrieving a
backtrace on OS X as verified by @alexcrichton. However, it still
breaks retrieving the values of parameters. This should be fixable in
the future via a proper location list...
Closes#7477
The general consensus is that we want to move away from conditions for I/O, and I propose a two-step plan for doing so:
1. Warn about unused `Result` types. When all of I/O returns `Result`, it will require you inspect the return value for an error *only if* you have a result you want to look at. By default, for things like `write` returning `Result<(), Error>`, these will all go silently ignored. This lint will prevent blind ignorance of these return values, letting you know that there's something you should do about them.
2. Implement a `try!` macro:
```
macro_rules! try( ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) }) )
```
With these two tools combined, I feel that we get almost all the benefits of conditions. The first step (the lint) is a sanity check that you're not ignoring return values at callsites. The second step is to provide a convenience method of returning early out of a sequence of computations. After thinking about this for awhile, I don't think that we need the so-called "do-notation" in the compiler itself because I think it's just *too* specialized. Additionally, the `try!` macro is super lightweight, easy to understand, and works almost everywhere. As soon as you want to do something more fancy, my answer is "use match".
Basically, with these two tools in action, I would be comfortable removing conditions. What do others think about this strategy?
----
This PR specifically implements the `unused_result` lint. I actually added two lints, `unused_result` and `unused_must_use`, and the first commit has the rationale for why `unused_result` is turned off by default.
In line with the dissolution of libextra - #8784 - this moves arena and glob into
their own respective modules. Updates .gitignore with the entries
doc/{arena,glob} in accordance.
In line with the dissolution of libextra - #8784 - moves arena to its own library libarena.
Changes based on PR #11787. Updates .gitignore to ignore doc/arena.
I attempted to implement the lint in two steps. My first attempt was a
default-warn lint about *all* unused results. While this attempt did indeed find
many possible bugs, I felt that the false-positive rate was too high to be
turned on by default for all of Rust.
My second attempt was to make unused-result a default-allow lint, but allow
certain types to opt-in to the notion of "you must use this". For example, the
Result type is now flagged with #[must_use]. This lint about "must use" types is
warn by default (it's different from unused-result).
The unused_must_use lint had a 100% hit rate in the compiler, but there's not
that many places that return Result right now. I believe that this lint is a
crucial step towards moving away from conditions for I/O (because all I/O will
return Result by default). I'm worried that this lint is a little too specific
to Result itself, but I believe that the false positive rate for the
unused_result lint is too high to make it useful when turned on by default.
cc #7621.
See the commit message. I'm not sure if we should merge this now, or wait until we can write `Clone::clone(x)` which will directly solve the above issue with perfect error messages.
This unfortunately changes an error like
error: mismatched types: expected `&&NotClone` but found `&NotClone`
into
error: type `NotClone` does not implement any method in scope named `clone`
Non-exhaustive change list:
* `self` is now present in argument lists (modulo type-checking code I don't trust myself to refactor)
* methods have the same calling convention as bare functions (including the self argument)
* the env param is gone from all bare functions (and methods), only used by closures and `proc`s
* bare functions can only be coerced to closures and `proc`s if they are statically resolved, as they now require creating a wrapper specific to that function, to avoid indirect wrappers (equivalent to `impl<..Args, Ret> Fn<..Args, Ret> for fn(..Args) -> Ret`) that might not be optimizable by LLVM and don't work for `proc`s
* refactored some `trans::closure` code, leading to the removal of `trans::glue::make_free_glue` and `ty_opaque_closure_ptr`
I'd forgotten to update them when I changed this a while ago; it now displays error messages linked to the struct/variant field, rather than the `#[deriving(Trait)]` line, for all traits.
This also adds a very large number of autogenerated tests. I can easily remove/tone down that commit if necessary.
This was the original intention of the privacy of structs, and it was
erroneously implemented before. A pub struct will now have default-pub fields,
and a non-pub struct will have default-priv fields. This essentially brings
struct fields in line with enum variants in terms of inheriting visibility.
As usual, extraneous modifiers to visibility are disallowed depend on the case
that you're dealing with.
Closes#11522
Now that procedural macros can be implemented outside of the compiler,
it's more important to have a reasonable API to work with. Here are the
basic changes:
* Rename SyntaxExpanderTTTrait to MacroExpander, SyntaxExpanderTT to
BasicMacroExpander, etc. I think "procedural macro" is the right
term for these now, right? The other option would be SynExtExpander
or something like that.
* Stop passing the SyntaxContext to extensions. This was only ever used
by macro_rules, which doesn't even use it anymore. I can't think of
a context in which an external extension would need it, and removal
allows the API to be significantly simpler - no more
SyntaxExpanderTTItemExpanderWithoutContext wrappers to worry about.
Now that procedural macros can be implemented outside of the compiler,
it's more important to have a reasonable API to work with. Here are the
basic changes:
* Rename SyntaxExpanderTTTrait to MacroExpander, SyntaxExpanderTT to
BasicMacroExpander, etc. I think "procedural macro" is the right
term for these now, right? The other option would be SynExtExpander
or something like that.
* Stop passing the SyntaxContext to extensions. This was only ever used
by macro_rules, which doesn't even use it anymore. I can't think of
a context in which an external extension would need it, and removal
allows the API to be significantly simpler - no more
SyntaxExpanderTTItemExpanderWithoutContext wrappers to worry about.
They all have to go into a single module at the moment unfortunately.
Ideally, the logging macros would live in std::logging, condition! would
live in std::condition, format! in std::fmt, etc. However, this
introduces cyclic dependencies between those modules and the macros they
use which the current expansion system can't deal with. We may be able
to get around this by changing the expansion phase to a two-pass system
but that's for a later PR.
Closes#2247
cc #11763
On my Gentoo Linux machine, the c-dynamic-dylib test is failing, because libcfoo can't be found. bar has a correct rpath for finding libfoo.so, but libfoo.so's rpath doesn't contain the right entries for finding libcfoo.
Below is the test failure on my machine. This test pass with this commit:
```
maketest: c-dynamic-dylib
----- /storage/home/achin/devel/rust/src/test/run-make/c-dynamic-dylib/ --------------------
------ stdout ---------------------------------------------
make[1]: Entering directory `/storage/home/achin/devel/rust/src/test/run-make/c-dynamic-dylib'
gcc -Wall -Werror -g -fPIC -m64 -L /storage/home/achin/devel/rust/x86_64-unknown-linux-gnu/test/run-make/c-dynamic-dylib -c -o /storage/home/achin/devel/rust/x86_64-unknown-linux-gnu/test/run-make/c-dynamic-dylib/libcfoo.o cfoo.c
gcc -Wall -Werror -g -fPIC -m64 -L /storage/home/achin/devel/rust/x86_64-unknown-linux-gnu/test/run-make/c-dynamic-dylib -o /storage/home/achin/devel/rust/x86_64-unknown-linux-gnu/test/run-make/c-dynamic-dylib/libcfoo.so /storage/home/achin/devel/rust/x86_64-unknown-linux-gnu/test/run-make/c-dynamic-dylib/libcfoo.o -shared
/storage/home/achin/devel/rust/x86_64-unknown-linux-gnu/stage2/bin/rustc --out-dir /storage/home/achin/devel/rust/x86_64-unknown-linux-gnu/test/run-make/c-dynamic-dylib -L /storage/home/achin/devel/rust/x86_64-unknown-linux-gnu/test/run-make/c-dynamic-dylib foo.rs
/storage/home/achin/devel/rust/x86_64-unknown-linux-gnu/stage2/bin/rustc --out-dir /storage/home/achin/devel/rust/x86_64-unknown-linux-gnu/test/run-make/c-dynamic-dylib -L /storage/home/achin/devel/rust/x86_64-unknown-linux-gnu/test/run-make/c-dynamic-dylib bar.rs
/storage/home/achin/devel/rust/x86_64-unknown-linux-gnu/test/run-make/c-dynamic-dylib/bar
rm /storage/home/achin/devel/rust/x86_64-unknown-linux-gnu/test/run-make/c-dynamic-dylib/libcfoo.o
make[1]: Leaving directory `/storage/home/achin/devel/rust/src/test/run-make/c-dynamic-dylib'
------ stderr ---------------------------------------------
/storage/home/achin/devel/rust/x86_64-unknown-linux-gnu/test/run-make/c-dynamic-dylib/bar: error while loading shared libraries: libcfoo.so: cannot open shared object file: No such file or directory
make[1]: *** [all] Error 127
------ ---------------------------------------------
```
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)
Renamed the invert() function in iter.rs to flip().
Also renamed the Invert<T> type to Flip<T>.
Some related code comments changed. Documentation that I could find has
been updated, and all the instances I could locate where the
function/type were called have been updated as well.
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.