Combine types and regions in Substs into one interleaved list.
Previously, `Substs` would contain types and regions, in two separate vectors, for example:
```rust
<X as Trait<'a, 'b, A, B>>::method::<'p, 'q, T, U>
/* corresponds to */
Substs { regions: ['a, 'b, 'p, 'q], types: [X, A, B, T, U] }
```
This PR continues the work started in #35605 by further removing the distinction.
A new abstraction over types and regions is introduced in the compiler, `Kind`.
Each `Kind` is a pointer (`&TyS` or `&Region`), with the lowest two bits used as a tag.
Two bits were used instead of just one (type = `0`, region = `1`) to allow adding more kinds.
`Substs` contain only a `Vec<Kind>`, with `Self` first, followed by regions and types (in the definition order):
```rust
Substs { params: [X, 'a, 'b, A, B, 'p, 'q, T, U] }
```
The resulting interleaved list has the property of being the concatenation of parameters for the (potentially) nested generic items it describes, and can be sliced back into those components:
```rust
params[0..5] = [X, 'a, 'b, A, B] // <X as Trait<'a, 'b, A, B>>
params[5..9] = ['p, 'q, T, U] // <_>::method::<'p, 'q, T, U>
```
r? @nikomatsakis
Macro expansions produce code tagged with debug locations that are completely different from the surrounding expressions. This wrecks havoc on debugger's ability the step over source lines.
In order to have a good line stepping behavior in debugger, we overwrite debug locations of macro expansions with that of the outermost expansion site.
Address ICEs running w/ incremental compilation and building glium
Fixes for various ICEs I encountered trying to build glium with incremental compilation enabled. Building glium now works. Of the 4 ICEs, I have test cases for 3 of them -- I didn't isolate a test for the last commit and kind of want to go do other things -- most notably, figuring out why incremental isn't saving much *effort*.
But if it seems worthwhile and I can come back and try to narrow down the problem.
r? @michaelwoerister
Fixes#34991Fixes#32015
The way we do HIR inlining introduces reads of the "Hir" into the graph,
but this Hir in fact belongs to other crates, so when we try to load
later, we ICE because the Hir nodes in question don't belond to the
crate (and we haven't done inlining yet). This pass rewrites those HIR
nodes to the metadata from which the inlined HIR was loaded.
Since LLVM reversed the order of the debug info graphs, we need to have
a compile unit that exists *before* any functions (`DISubprogram`s) are
created. This allows the LLVM debug info builder to automatically link
the functions to the compile unit.
When items are inlined from extern crates, the filename in the debug info
is taken from the FileMap that's serialized in the rlib metadata.
Currently this is just FileMap.name, which is whatever path is passed to rustc.
Since libcore and libstd are built by invoking rustc with relative paths,
they wind up with relative paths in the rlib, and when linked into a binary
the debug info uses relative paths for the names, but since the compilation
directory for the final binary, tools trying to read source filenames
will wind up with bad paths. We noticed this in Firefox with source
filenames from libcore/libstd having bad paths.
This change stores an absolute path in FileMap.abs_path, and uses that
if available for writing debug info. This is not going to magically make
debuggers able to find the source, but it will at least provide sensible
paths.
prefer `if let` to match with `None => ()` arm in some places
Casual grepping revealed some places in the codebase (some of which
antedated `if let`'s December 2014 stabilization in c200ae5a) where we
were using a match with a `None => ()` arm where (in the present
author's opinion) an `if let` conditional would be more readable. (Other
places where matching to the unit value did seem to better express the
intent were left alone.)
It's likely that we don't care about making such trivial,
non-functional, sheerly æsthetic changes.
But if we do, this is a patch.
Casual grepping revealed some places in the codebase (some of which
antedated `if let`'s December 2014 stabilization in c200ae5a) where we
were using a match with a `None => ()` arm where (in the present
author's opinion) an `if let` conditional would be more readable. (Other
places where matching to the unit value did seem to better express the
intent were left alone.)
It's likely that we don't care about making such trivial,
non-functional, sheerly æsthetic changes.
But if we do, this is a patch.