Generating the coverage map
@tmandry @wesleywiser
rustc now generates the coverage map and can support (limited)
coverage report generation, at the function level.
Example commands to generate a coverage report:
```shell
$ BUILD=$HOME/rust/build/x86_64-unknown-linux-gnu
$ $BUILD/stage1/bin/rustc -Zinstrument-coverage \
$HOME/rust/src/test/run-make-fulldeps/instrument-coverage/main.rs
$ LLVM_PROFILE_FILE="main.profraw" ./main
called
$ $BUILD/llvm/bin/llvm-profdata merge -sparse main.profraw -o main.profdata
$ $BUILD/llvm/bin/llvm-cov show --instr-profile=main.profdata main
```
![rust coverage report only 20200706](https://user-images.githubusercontent.com/3827298/86697299-1cbe8f80-bfc3-11ea-8955-451b48626991.png)
r? @wesleywiser
Rust compiler MCP rust-lang/compiler-team#278
Relevant issue: #34701 - Implement support for LLVMs code coverage instrumentation
Bump version to 1.47
This also bumps to a more recent rustfmt version, just to keep us relatively up to date (though almost nothing has changed in rustfmt we use beyond bumps to the parser infra). No formatting changes as a result of this.
r? @pietroalbini
This now reuses `fn discriminant_ty` in project, removing
some code duplication. Doing so made me realize that
we previously had a disagreement about the discriminant
type of generators, with MIR using `u32` and codegen and
trait selection using `i32`.
We now always use `u32`.
Note that the output of `unpretty-debug.stdout` has changed. In that
test the hash values are normalized from a symbol numbers to small
numbers like "0#0" and "0#1". The increase in the number of static
symbols must have caused the original numbers to contain more digits,
resulting in different pretty-printing prior to normalization.
This is a re-attempt of #72389 (which was reverted in #73594)
Instead of using `ExpnKind::Desugaring` to represent operators, this PR
checks the lang item directly.
Fixes#70718
This commit allows making associated items (e.g. associated functions
and types) into lang items via the `#[lang]` attribute. This allows such
items to be accessed directly, rather than by iterating over the parent
item's associated items.
I've added `FnOnce::Output` as a lang item, and updated one old usage to
use the new lang item. The remaining uses can be updated separately.
Change heuristic for determining range literal
Currently, rustc uses a heuristic to determine if a range expression is
not a literal based on whether the expression looks like a function call
or struct initialization. This fails for range literals whose
lower/upper bounds are the results of function calls. A possibly-better
heuristic is to check if the expression contains `..`, required in range
literals.
Of course, this is also not perfect; for example, if the range
expression is a struct which includes some text with `..` this will
fail, but in general I believe it is a better heuristic.
A better alternative altogether is to add the `QPath::LangItem` enum
variant suggested in #60607. I would be happy to do this as a precursor
to this patch if someone is able to provide general suggestions on how
usages of `QPath` need to be changed later in the compiler with the
`LangItem` variant.
Closes#73553
Currently, rustc uses a heuristic to determine if a range expression is
not a literal based on whether the expression looks like a function call
or struct initialization. This fails for range literals whose
lower/upper bounds are the results of function calls. A possibly-better
heuristic is to check if the expression contains `..`, required in range
literals.
Of course, this is also not perfect; for example, if the range
expression is a struct which includes some text with `..` this will
fail, but in general I believe it is a better heuristic.
A better alternative altogether is to add the `QPath::LangItem` enum
variant suggested in #60607. I would be happy to do this as a precursor
to this patch if someone is able to provide general suggestions on how
usages of `QPath` need to be changed later in the compiler with the
`LangItem` variant.
Closes#73553
first stage of implementing LLVM code coverage
This PR replaces #70680 (WIP toward LLVM Code Coverage for Rust) since I am re-implementing the Rust LLVM code coverage feature in a different part of the compiler (in MIR pass(es) vs AST).
This PR updates rustc with `-Zinstrument-coverage` option that injects the llvm intrinsic `instrprof.increment()` for code generation.
This initial version only injects counters at the top of each function, and does not yet implement the required coverage map.
Upcoming PRs will add the coverage map, and add more counters and/or counter expressions for each conditional code branch.
Rust compiler MCP https://github.com/rust-lang/compiler-team/issues/278
Relevant issue: #34701 - Implement support for LLVMs code coverage instrumentation
***[I put together some development notes here, under a separate branch.](cfa0b21d34/src/test/codegen/coverage-experiments/README-THIS-IS-TEMPORARY.md)***
This initial version only injects counters at the top of each function.
Rust Coverage will require injecting additional counters at each
conditional code branch.
Use min_specialization in the remaining rustc crates
This adds a lot of `transmute` calls to replace the unsound uses of specialization.
It's ugly, but at least it's honest about what's going on.
cc #71420, @RalfJung
Clean up type alias impl trait implementation
- Removes special case for top-level impl trait
- Removes associated opaque types
- Forbid lifetime elision in let position impl trait. This is consistent with the behavior for inferred types.
- Handle lifetimes in type alias impl trait more uniformly with other parameters
cc #69323
cc #63063Closes#57188Closes#62988Closes#69136Closes#73061
expand: More precise locations for expansion-time lints
First commit: a macro expansion doesn't have a `NodeId` associated with it, but it has a parent `DefId` which we can use for linting.
The observable effect is that lints associated with macro expansions can now be `allow`ed at finer-grained level than whole crate.
Second commit: each macro definition has a `NodeId` which we can use for linting, unless that macro definition was decoded from other crate.
Fixes#69977
When we parse a chain of method calls like `foo.a().b().c()`, each
`MethodCallExpr` gets assigned a span that starts at the beginning of
the call chain (`foo`). While this is useful for diagnostics, it means
that `Location::caller` will return the same location for every call
in a call chain.
This PR makes us separately record the span of the function name and
arguments for a method call (e.g. `b()` in `foo.a().b().c()`). This
`Span` is passed through HIR lowering and MIR building to
`TerminatorKind::Call`, where it is used in preference to
`Terminator.source_info.span` when determining `Location::caller`.
This new span is also useful for diagnostics where we want to emphasize
a particular method call - for an example, see
https://github.com/rust-lang/rust/pull/72389#discussion_r436035990
Improve inline asm error diagnostics
Previously we were just using the raw LLVM error output (with line, caret, etc) as the diagnostic message, which ends up looking rather out of place with our existing diagnostics.
The new diagnostics properly format the diagnostics and also take advantage of LLVM's per-line `srcloc` attribute to map an error in inline assembly directly to the relevant line of source code.
Incidentally also fixes#71639 by disabling `srcloc` metadata during LTO builds since we don't know what crate it might have come from. We can only resolve `srcloc`s from the currently crate since it indexes into the source map for the current crate.
Fixes#72664Fixes#71639
r? @petrochenkov
### Old style
```rust
#![feature(llvm_asm)]
fn main() {
unsafe {
let _x: i32;
llvm_asm!(
"mov $0, $1
invalid_instruction $0, $1
mov $0, $1"
: "=&r" (_x)
: "r" (0)
:: "intel"
);
}
}
```
```
error: <inline asm>:3:14: error: invalid instruction mnemonic 'invalid_instruction'
invalid_instruction ecx, eax
^~~~~~~~~~~~~~~~~~~
--> src/main.rs:6:9
|
6 | / llvm_asm!(
7 | | "mov $0, $1
8 | | invalid_instruction $0, $1
9 | | mov $0, $1"
... |
12 | | :: "intel"
13 | | );
| |__________^
```
### New style
```rust
#![feature(asm)]
fn main() {
unsafe {
asm!(
"mov {0}, {1}
invalid_instruction {0}, {1}
mov {0}, {1}",
out(reg) _,
in(reg) 0i64,
);
}
}
```
```
error: invalid instruction mnemonic 'invalid_instruction'
--> test.rs:7:14
|
7 | invalid_instruction {0}, {1}
| ^
|
note: instantiated into assembly here
--> <inline asm>:3:14
|
3 | invalid_instruction rax, rcx
| ^^^^^^^^^^^^^^^^^^^
```
This commit also include the following changes:
* Remove unused `hir::Map::as_local_node_id` method
* Remove outdated comment about `hir::Map::local_def_id` method
* Remove confusing `GlobMap` type alias
* Use `LocalDefId` instead of `DefId` in `extern_crate_map`
* Use `LocalDefId` instead of `DefId` in `maybe_unused_extern_crates`
* Modify `extern_mod_stmt_cnum` query to accept a `LocalDefId` instead of a `DefId`