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.
Refactored the file quite a bit, I can add unit tests if desired. There's a few changes from the previous version's behavior:
- destination directory will be created if it doesn't exist
- strings and file is written as unicode
I have a few questions, but will ask them in #11362.
Set "Dwarf Version" to 2 on OS X to avoid toolchain incompatibility, and
set "Debug Info Version" to prevent debug info from being stripped from
bitcode.
Fixes#11352.
Set "Dwarf Version" to 2 on OS X to avoid toolchain incompatibility, and
set "Debug Info Version" to prevent debug info from being stripped from
bitcode.
Fixes#11352.
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`
In two ways:
- for a plain `fail!(a)` we make the generic part of `begin_unwind` as small as possible (makes `fn main() { fail!() }` compile 2-3x faster, due to less monomorphisation bloat)
- for `fail!("format {}", "string")`, we avoid touching the generics completely by doing the formatting in a specialised function, which (with optimisations) saves a function call at the call-site of `fail!`. (This one has significantly less benefit than the first.)
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`
This ends up saving a single `call` instruction in the optimised code,
but saves a few hundred lines of non-optimised IR for `fn main() {
fail!("foo {}", "bar"); }` (comparing against the minimal generic
baseline from the parent commit).
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 splits the vast majority of the code path taken by
`fail!()` (`begin_unwind`) into a separate non-generic inline(never)
function, so that uses of `fail!()` only monomorphise a small amount of
code, reducing code bloat and making very small crates compile faster.
This makes error messages about (e.g.) `#[deriving(Clone)] struct Foo {
x: Type }` point at `x: Type` rather than `Clone` in the header (while
still referring to the `#[deriving(Clone)]` in the expansion info).