# Summary
This patch introduces the `_` token into the type grammar, with the meaning "infer this type".
With this change, the following two lines become equivalent:
```
let x = foo();
let x: _ = foo();
```
But due to its composability, it enables partial type hints like this:
```
let x: Bar<_> = baz();
```
Using it on the item level is explicitly forbidden, as the Rust language does not enable global type inference by design.
This implements the feature requested in https://github.com/mozilla/rust/issues/9508.
# Things requiring clarification
- The change to enable it is very small, but I have only limited understanding of the related code, so the approach here might be wrong.
- In particular, while this patch works, it does so in a way not originally intended according to the code comments.
- This probably needs more tests, or rather feedback for which tests are still missing.
- I'm unsure how this interacts with lifetime parameters, and whether it is correct in regard to them.
- Partial type hints on the right side of `as` like `&foo as *_` work in both a normal function contexts and in constexprs like `static foo: *int = &'static 123 as *_`. The question is whether this should be allowed in general.
# Todo for this PR
- The manual and tutorial still needs updating.
# Bugs I'm unsure how to fix
- Requesting inference for the top level of the right hand side of a `as` fails to infer correctly, even if all possible hints are given:
```
.../type_hole_1.rs:35:18: 35:22 error: the type of this value must be known in this context
.../type_hole_1.rs:35 let a: int = 1u32 as _;
^~~~
```
Add some more infrastructure support for demangling `$`-sequences, as well as fixing demangling of closure symbol names if there's more than one closure in a function.
rustc: make stack traces print for .span_bug/.bug.
Previously a call to either of those to diagnostic printers would defer
to the `fatal` equivalents, which explicitly silence the stderr
printing, including a stack trace from `RUST_LOG=std::rt::backtrace`.
This splits the bug printers out to their own diagnostic type so that
things work properly.
Also, this removes the `Ok(...)` that was being printed around the
subtask's stderr output.
lint: add lint for use of a `~[T]`.
This is useless at the moment (since pretty much every crate uses
`~[]`), but should help avoid regressions once completely removed from a
crate.
## read+write modifier '+'
This small sugar was left out in the original implementation (#5359).
When an output operand with the '+' modifier is encountered, we store the index of that operand alongside the expression to create and append an input operand later. The following lines are equivalent:
```
asm!("" : "+m"(expr));
asm!("" : "=m"(expr) : "0"(expr));
```
## misplaced options and clobbers give a warning
It's really annoying when a small typo might change behavior without any warning.
```
asm!("mov $1, $0" : "=r"(x) : "r"(8u) : "cc" , "volatile");
//~^ WARNING expected a clobber, but found an option
```
## liveness
Fixed incorrect order of propagation.
Sometimes it caused spurious warnings in code: `warning: value assigned to `i` is never read, #[warn(dead_assignment)] on by default`
~~Note: Rebased on top of another PR. (uses other changes)~~
* [x] Implement read+write
* [x] Warn about misplaced options
* [x] Fix liveness (`dead_assignment` lint)
* [x] Add all tests
This commit goes back to using `gensym` to generate unique tokens to put into
the names of closures, allowing closures to be able to get demangled in
backtraces.
Closes#12400
Previously a call to either of those to diagnostic printers would defer
to the `fatal` equivalents, which explicitly silence the stderr
printing, including a stack trace from `RUST_LOG=std::rt::backtrace`.
This splits the bug printers out to their own diagnostic type so that
things work properly.
Also, this removes the `Ok(...)` that was being printed around the
subtask's stderr output.
For the following code snippet:
```rust
struct Foo { bar: int }
fn foo1(x: &Foo) -> &int {
&x.bar
}
```
This PR generates the following error message:
```rust
test.rs:2:1: 4:2 note: consider using an explicit lifetime parameter as shown: fn foo1<'a>(x: &'a Foo) -> &'a int
test.rs:2 fn foo1(x: &Foo) -> &int {
test.rs:3 &x.bar
test.rs:4 }
test.rs:3:5: 3:11 error: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
test.rs:3 &x.bar
^~~~~~
```
Currently it does not support methods.
The `~str` type is not long for this world as it will be superseded by the
soon-to-come DST changes for the language. The new type will be
`~Str`, and matching over the allocation will no longer be supported.
Matching on `&str` will continue to work, in both a pre and post DST world.
Some types of error are caused by missing lifetime parameter on function
or method declaration. In such cases, this commit generates some
suggestion about what the function declaration could be. This does not
support method declaration yet.
There is a broader revision (that does this across the board) pending
in #12675, but that is awaiting the arrival of more data (to decide
whether to keep OptVec alive by using a non-Vec internally).
For this code, the representation of lifetime lists needs to be the
same in both ScopeChain and in the ast and ty structures. So it
seemed cleanest to just use `vec_ng::Vec`, now that it has a cheaper
empty representation than the current `vec` code.
The `-g` flag does not take an argument anymore while the argument to `--debuginfo` becomes mandatory. This change makes it possible again to run the compiler like this:
`rustc -g ./file.rs`
This did not work before because `./file.rs` was misinterpreted as the argument to `-g`. In order to get limited debuginfo, one now has to use `--debuginfo=1`.
It is often convenient to have forms of weak linkage or other various types of
linkage. Sadly, just using these flavors of linkage are not compatible with
Rust's typesystem and how it considers some pointers to be non-null.
As a compromise, this commit adds support for weak linkage to external symbols,
but it requires that this is only placed on extern statics of type `*T`.
Codegen-wise, we get translations like:
```rust
// rust code
extern {
#[linkage = "extern_weak"]
static foo: *i32;
}
// generated IR
@foo = extern_weak global i32
@_some_internal_symbol = internal global *i32 @foo
```
All references to the rust value of `foo` then reference `_some_internal_symbol`
instead of the symbol `_foo` itself. This allows us to guarantee that the
address of `foo` will never be null while the value may sometimes be null.
An example was implemented in `std::rt::thread` to determine if
`__pthread_get_minstack()` is available at runtime, and a test is checked in to
use it for a static value as well. Function pointers a little odd because you
still need to transmute the pointer value to a function pointer, but it's
thankfully better than not having this capability at all.
Thanks to @bnoordhuis for the original patch, most of this work is still his!
It is often convenient to have forms of weak linkage or other various types of
linkage. Sadly, just using these flavors of linkage are not compatible with
Rust's typesystem and how it considers some pointers to be non-null.
As a compromise, this commit adds support for weak linkage to external symbols,
but it requires that this is only placed on extern statics of type `*T`.
Codegen-wise, we get translations like:
// rust code
extern {
#[linkage = "extern_weak"]
static foo: *i32;
}
// generated IR
@foo = extern_weak global i32
@_some_internal_symbol = internal global *i32 @foo
All references to the rust value of `foo` then reference `_some_internal_symbol`
instead of the symbol `_foo` itself. This allows us to guarantee that the
address of `foo` will never be null while the value may sometimes be null.
An example was implemented in `std::rt::thread` to determine if
`__pthread_get_minstack()` is available at runtime, and a test is checked in to
use it for a static value as well. Function pointers a little odd because you
still need to transmute the pointer value to a function pointer, but it's
thankfully better than not having this capability at all.
- Repurposes `MoveData.assignee_ids` to mean only `=` but not `+=`, so
that borrowck effectively classifies all expressions into assignees,
uses or both.
- Removes two `span_err` in liveness analysis, which are now borrowck's
responsibilities.
Closes#12527.
Refactored get_metadata_section to return a Result<MetadataBlob,~str> instead of a Option<MetadataBlob>. This provides more clarity to the user through the debug output when using --ls.
This is kind of a continuation of my original closed pull request 2 months ago (#11544), but I think the time-span constitutes a new pull request.
* `Ord` inherits from `Eq`
* `TotalOrd` inherits from `TotalEq`
* `TotalOrd` inherits from `Ord`
* `TotalEq` inherits from `Eq`
This is a partial implementation of #12517.
If #[feature(default_type_parameters)] is enabled for a crate, then
deriving(Hash) will expand with Hash<W: Writer> instead of Hash<SipState> so
more hash algorithms can be used.
This leverages the new hashing framework and hashmap implementation to provide a
much speedier hashing algorithm for node ids and def ids. The hash algorithm
used is currentl FNV hashing, but it's quite easy to swap out.
I originally implemented hashing as the identity function, but this actually
ended up in slowing down rustc compiling libstd from 8s to 13s. I would suspect
that this is a result of a large number of collisions.
With FNV hashing, we get these timings (compiling with --no-trans, in seconds):
| | before | after |
|-----------|---------:|--------:|
| libstd | 8.324 | 6.703 |
| stdtest | 47.674 | 46.857 |
| libsyntax | 9.918 | 8.400 |
On Windows, `LLVMRustGetLastError()` may return non-utf8 mojibake string
if system uses non-English locale. It caused ICE when llvm fails.
This patch doesn't fix the real problem, but just make rustc not die.
On Windows, `LLVMRustGetLastError()` may return non-utf8 mojibake string
if system uses non-English locale. It caused ICE when llvm fails.
This patch doesn't fix the real problem, but just make rustc not die.
Cosmetic changes at best, but there are so many such typos that I couldn't ignore them. :) Some occurrences of typos are linked to the generated documentations but no changes should break the builds.