Visit statement and expression attributes in the AST visitor
Currently, these attributes are not visited, so they are not gated feature checked in the post expansion visitor. This only affects crates using `#![feature(stmt_expr_attributes)]`.
r? @nrc
Fix issue #34101
Fix issue #34101: do not track subcontent of type with dtor nor gather flags for untracked content.
(Includes a regression test, which needed to go into `compile-fail/`
due to weaknesses when combining `#[deny(warnings)]` with
`tcx.sess.span_warn(..)`)
The root of the problem is that a string literal pattern is essentially of
the form `&LITERAL`, in a single block, while match checking wants to
split that.
To fix that, I added a type field to the patterns in match checking,
which allows us to distinguish between a full and split pattern.
That file is ugly and needs to be cleaned. However, `trans::_match` calls
it, so I think we should delay the cleanup until we kill that.
Fixes#30240
Remove the old FOLLOW checking (aka `check_matcher_old`).
It was supposed to be removed at the next release cycle but is still in the tree since like 6 months.
Potential breaking change, since some cases (such as #25658) will change from a warning to an error. But the warning stating that it will be a hard error in the next release has been there for 6 months now.
I think it's safe to break this code. ^_^
(Includes a regression test, which needed to go into `compile-fail/`
due to weaknesses when combining `#[deny(warnings)]` with
`tcx.sess.span_warn(..)`)
(updated with review feedback from arielb1.)
rustc: add ReErased to be used by trait selection, MIR and trans.
`ReErased` replaces `ReStatic` (i.e. `'static`) for erasing regions.
Using a distinct lifetime helps prevent accidental mix-ups between the two.
It also allows cleaner type printing (see test changes), including in symbol names:
```rust
str..pattern..CharSearcher$LT$$u27$static$GT$::drop.30560::h840c2f2afc03bbea // before
str..pattern..CharSearcher::drop.30561::h6bd31d2af614377a // after
```
Not that we should be producing symbols this way, but it's still better.
Fix a regression in the configuration folder
This fixes#34028, a regression caused by #33706 in which unconfigured impl items generated by a macro in an impl item position are not removed.
r? @nrc
Projection cache and better warnings for #32330
This PR does three things:
- it lays the groundwork for the more precise subtyping rules discussed in #32330, but does not enable them;
- it issues warnings when the result of a leak-check or subtyping check relies on a late-bound region which will late become early-bound when #32330 is fixed;
- it introduces a cache for projection in the inference context.
I'm not 100% happy with the approach taken by the cache here, but it seems like a step in the right direction. It results in big wins on some test cases, but not as big as previous versions -- I think because it is caching the `Vec<Obligation>` (whereas before I just returned the normalized type with an empty vector). However, that change was needed to fix an ICE in @alexcrichton's future-rs module (I haven't fully tracked the cause of that ICE yet). Also, because trans/the collector use a fresh inference context for every call to `fulfill_obligation`, they don't profit nearly as much from this cache as they ought to.
Still, here are the results from the future-rs `retry.rs`:
```
06:26 <nmatsakis> time: 6.246; rss: 44MB item-bodies checking
06:26 <nmatsakis> time: 54.783; rss: 63MB translation item collection
06:26 <nmatsakis> time: 140.086; rss: 86MB translation
06:26 <nmatsakis> time: 0.361; rss: 46MB item-bodies checking
06:26 <nmatsakis> time: 5.299; rss: 63MB translation item collection
06:26 <nmatsakis> time: 12.140; rss: 86MB translation
```
~~Another example is the example from #31849. For that, I get 34s to run item-bodies without any cache. The version of the cache included here takes 2s to run item-bodies type-checking. An alternative version which doesn't track nested obligations takes 0.2s, but that version ICEs on @alexcrichton's future-rs (and may well be incorrect, I've not fully convinced myself of that). So, a definite win, but I think there's definitely room for further progress.~~
Pushed a modified version which improves performance of the case from #31849:
```
lunch-box. time rustc --stage0 ~/tmp/issue-31849.rs -Z no-trans
real 0m33.539s
user 0m32.932s
sys 0m0.570s
lunch-box. time rustc --stage2 ~/tmp/issue-31849.rs -Z no-trans
real 0m0.195s
user 0m0.154s
sys 0m0.042s
```
Some sort of cache is also needed for unblocking further work on lazy normalization, since that will lean even more heavily on the cache, and will also require cycle detection.
r? @arielb1
Add AST validation pass and move some checks to it
The purpose of this pass is to catch constructions that fit into AST data structures, but not permitted by the language. As an example, `impl`s don't have visibilities, but for convenience and uniformity with other items they are represented with a structure `Item` which has `Visibility` field.
This pass is intended to run after expansion of macros and syntax extensions (and before lowering to HIR), so it can catch erroneous constructions that were generated by them. This pass allows to remove ad hoc semantic checks from the parser, which can be overruled by syntax extensions and occasionally macros.
The checks can be put here if they are simple, local, don't require results of any complex analysis like name resolution or type checking and maybe don't logically fall into other passes. I expect most of errors generated by this pass to be non-fatal and allowing the compilation to proceed.
I intend to move some more checks to this pass later and maybe extend it with new checks, like, for example, identifier validity. Given that syntax extensions are going to be stabilized in the measurable future, it's important that they would not be able to subvert usual language rules.
In this patch I've added two new checks - a check for labels named `'static` and a check for lifetimes and labels named `'_`. The first one gives a hard error, the second one - a future compatibility warning.
Fixes https://github.com/rust-lang/rust/issues/33059 ([breaking-change])
cc https://github.com/rust-lang/rfcs/pull/1177
r? @nrc
stable features lint warning mentions version stabilized
To accomplish this, we alter the checks in `rustc::middle::stability` to
use the `StabilityLevel` defined in `syntax::attr` (which includes the
version in which the feature was stabilized) rather than the local
`StabilityLevel` in the same module, and make the
`declared_stable_lang_features` field of
`syntax::feature_gate::Features` hold a Vec of feature-name, span
tuples (in analogy to the `declared_lib_features` field) rather than
just spans.
Fixes#33394.
![stable_features_version_lint_before_and_after](https://cloud.githubusercontent.com/assets/1076988/15659237/5d952a3a-267c-11e6-9181-c9e612eefd7d.png)
r? @brson (tagging Brian because he [wrote](https://github.com/rust-lang/rust/pull/21958) the lint)
Reject a LHS formed of a single sequence TT during `macro_rules!` checking.
This was already rejected during expansion. Encountering malformed LHS or RHS during expansion is now considered a bug.
Follow up to #33689.
r? @pnkfelix
Note: this can break code that defines such macros but does not use them.
When we do a "HR subtype" check, we replace all late-bound regions (LBR)
in the subtype with fresh variables, and skolemize the late-bound
regions in the supertype. If those skolemized regions from the supertype
wind up being super-regions (directly or indirectly) of either
- another skolemized region; or,
- some region that pre-exists the HR subtype check
- e.g., a region variable that is not one of those created
to represent bound regions in the subtype
then the subtype check fails.
What will change when we fix#32330 is that some of the LBR in the
subtype may become early-bound. In that case, they would no longer be in
the "permitted set" of variables that can be related to a skolemized
type.
So the foundation for this warning is to collect variables that we found
to be related to a skolemized type. For each of them, we have a
`BoundRegion` which carries a `Issue32330` flag. We check whether any of
those flags indicate that this variable was created from a lifetime
that will change from late- to early-bound. If so, we issue a warning
indicating that the results of compilation may change.
This is imperfect, since there are other kinds of code that will not
compile once #32330 is fixed. However, it fixes the errors observed in
practice on crater runs.
Currently, we consider region subtyping a failure
if a skolemized lifetime is relatable to any
other lifetime in any way at all. But a more precise
formulation is to say that a skolemized lifetime:
- must not have any *incoming* edges in the region graph
- only has *outgoing* edges to nodes that are `'static`
To enforce the latter requirement, we add edges from `'static -> 'x` for
each lifetime '`x' reachable from a skolemized region.
We now have to add a new `pop_skolemized` routine to do cleanup.
Whereas before if there were *any* edges relating to a skolemized
region, we would return `Err` and hence rollback the transaction, we now
tolerate some edges and return `Ok`. Therefore, the `pop_skolemized`
routine runs and cleans up those edges.
To accomplish this, we alter the checks in `rustc::middle::stability` to
use the `StabilityLevel` defined in `syntax::attr` (which includes the
version in which the feature was stabilized) rather than the local
`StabilityLevel` in the same module, and make the
`declared_stable_lang_features` field of
`syntax::feature_gate::Features` hold a Vec of feature-name, span
tuples (in analogy to the `declared_lib_features` field) rather than
just spans.
This is in the matter of issue #33394.
refactor autoderef to avoid prematurely registering obligations
Refactor `FnCtxt::autoderef` to use an external iterator and to not
register any obligation from the main autoderef loop, but rather to
register them after (and if) the loop successfully completes.
Fixes#24819Fixes#25801Fixes#27631Fixes#31258Fixes#31964Fixes#32320Fixes#33515Fixes#33755
r? @eddyb
Increase spacing in error format for readability.
Two small tweaks that seem to help readability quite a bit:
* Add spacing header<->snippet, but use the |> on the side for visual consistency
* Fix#33819
* Fix#33763
* Move format-sensitive test (issue-26480 in cfail) to ui test
r? @nikomatsakis
Perform `cfg` attribute processing during macro expansion and fix bugs
This PR refactors `cfg` attribute processing and fixes bugs. More specifically:
- It merges gated feature checking for stmt/expr attributes, `cfg_attr` processing, and `cfg` processing into a single fold.
- This allows feature gated `cfg` variables to be used in `cfg_attr` on unconfigured items. All other feature gated attributes can already be used on unconfigured items.
- It performs `cfg` attribute processing during macro expansion instead of after expansion so that macro-expanded items are configured the same as ordinary items. In particular, to match their non-expanded counterparts,
- macro-expanded unconfigured macro invocations are no longer expanded,
- macro-expanded unconfigured macro definitions are no longer usable, and
- feature gated `cfg` variables on macro-expanded macro definitions/invocations are now errors.
This is a [breaking-change]. For example, the following would break:
```rust
macro_rules! m {
() => {
#[cfg(attr)]
macro_rules! foo { () => {} }
foo!(); // This will be an error
macro_rules! bar { () => { fn f() {} } }
#[cfg(attr)] bar!(); // This will no longer be expanded ...
fn g() { f(); } // ... so that `f` will be unresolved.
#[cfg(target_thread_local)] // This will be a gated feature error
macro_rules! baz { () => {} }
}
}
m!();
```
r? @nrc
Fix `asm-misplaced-option` on ARM/AArch64
This fixesrust-lang/rust#33737. Of course, since we don't run `make check` for ARM cross builds, you probably won't notice it.
Fixes to mir dataflow
Fixes to mir dataflow
This collects a bunch of changes to `rustc_borrowck::borrowck::dataflow` (which others have pointed out should probably migrate to some crate that isn't tied to the borrow-checker -- but I have not attempted that here, especially since there are competing approaches to dataflow that we should also evaluate).
These changes:
1. Provide a family of related analyses: MovingOutStatements (which is what the old AST-based dataflo computed), as well as MaybeInitialized, MaybeUninitalized, and DefinitelyInitialized.
* (The last two are actually inverses of each other; we should pick one and drop the other.)
2. Fix bugs in the pre-existing analysis implementation, which was untested and thus some obvious bugs went unnoticed, which brings us to the third point:
3. Add a unit test infrastructure for the MIR dataflow analysis.
* The tests work by adding a new intrinsic that is able to query the analysis state for a particular expression (technically, a particular L-value).
* See the examples in compile-fail/mir-dataflow/inits-1.rs and compile-fail/mir-dataflow/uninits-1.rs
* These tests are only checking the results for MaybeInitialized, MaybeUninitalized, and DefinitelyInitialized; I am not sure if it will be feasible to generalize this testing strategy to the MovingOutStatements dataflow operator.
Make sure that macros that didn't pass LHS checking are not expanded.
This avoid duplicate errors for things like invalid fragment specifiers, or
parsing errors for ambiguous macros.
Save metadata even with -Z no-trans (e.g. for multi-crate cargo check).
Removes the item symbol map in metadata, as we can now generate them in a deterministic manner.
The `-Z no-trans` change lets the LLVM passes and linking run, but with just metadata and no code.
It fails while trying to link a binary because there's no `main` function, which is correct but not good UX.
There's also no way to easily throw away all of the artifacts to rebuild with actual code generation.
We might want `cargo check` to do that using cargo-internal information and then it would just work.
cc @alexcrichton @nikomatsakis @Aatch @michaelwoerister
Refactor `FnCtxt::autoderef` to use an external iterator and to not
register any obligation from the main autoderef loop, but rather to
register them after (and if) the loop successfully completes.
Fixes#24819Fixes#25801Fixes#27631Fixes#31258Fixes#31964Fixes#32320Fixes#33515Fixes#33755
Allow `concat_idents!` in type positions as well as in expression positions
This allows the `concat_idents!` macro in type positions as well as in expression positions.
r? @nrc
rustc: Add a new crate type, cdylib
This commit is an implementation of [RFC 1510] which adds a new crate type,
`cdylib`, to the compiler. This new crate type differs from the existing `dylib`
crate type in a few key ways:
* No metadata is present in the final artifact
* Symbol visibility rules are the same as executables, that is only reachable
`extern` functions are visible symbols
* LTO is allowed
* All libraries are always linked statically
This commit is relatively simple by just plubming the compiler with another
crate type which takes different branches here and there. The only major change
is an implementation of the `Linker::export_symbols` function on Unix which now
actually does something. This helps restrict the public symbols from a cdylib on
Unix.
With this PR a "hello world" `cdylib` is 7.2K while the same `dylib` is 2.4MB,
which is some nice size savings!
[RFC 1510]: https://github.com/rust-lang/rfcs/pull/1510Closes#33132
This commit is an implementation of [RFC 1510] which adds a new crate type,
`cdylib`, to the compiler. This new crate type differs from the existing `dylib`
crate type in a few key ways:
* No metadata is present in the final artifact
* Symbol visibility rules are the same as executables, that is only reachable
`extern` functions are visible symbols
* LTO is allowed
* All libraries are always linked statically
This commit is relatively simple by just plubming the compiler with another
crate type which takes different branches here and there. The only major change
is an implementation of the `Linker::export_symbols` function on Unix which now
actually does something. This helps restrict the public symbols from a cdylib on
Unix.
With this PR a "hello world" `cdylib` is 7.2K while the same `dylib` is 2.4MB,
which is some nice size savings!
[RFC 1510]: https://github.com/rust-lang/rfcs/pull/1510Closes#33132
Only print parameters with elided lifetimes in elision error messages.
When displaying the function parameters for a lifetime elision error message,
this changes it to first filter out the parameters that don't have elided
lifetimes.
Fixes#30255.
Add regression tests for error message when using enum variant as a type
I'm guessing these were actually fixed with PR #27085.
Closes#21225Closes#19197
Fix for old school error issues, improvements to new school
This PR:
* Fixes some old school error issues, specifically #33559, #33543, #33366
* Improves wording borrowck errors with match patterns
* De-emphasize multi-line spans, so we don't color the single source character when we're trying to say "span starts here"
* Rollup of #33392 (which should help fix#33390)
r? @nikomatsakis
When displaying the function parameters for a lifetime elision error message,
this changes it to first filter out the parameters that don't have elided
lifetimes.
Fixes#30255.
Warnings for issue #32330
This is an extension of the previous PR that issues warnings in more situations than before. It does not handle *all* cases of #32330 but I believe it issues warnings for all cases I've seen in practice.
Before merging I'd like to address:
- open a good issue explaining the problem and how to fix it (I have a [draft writeup][])
- work on the error message, which I think is not as clear as it could/should be (suggestions welcome)
r? @aturon
[draft writeup]: https://gist.github.com/nikomatsakis/631ec8b4af9a18b5d062d9d9b7d3d967
Replace the obligation forest with a graph
In the presence of caching, arbitrary nodes in the obligation forest can be merged, which makes it a general graph. Handle it as such, using cycle-detection algorithms in the processing.
I should do performance measurements sometime.
This was pretty much written as a proof-of-concept. Please help me write this in a less-ugly way. I should also add comments explaining what is going on.
r? @nikomatsakis
Remove ExplicitSelf from HIR
`self` argument is already kept in the argument list and can be retrieved from there if necessary, so there's no need for the duplication.
The same changes can be applied to AST, I'll make them in the next breaking batch.
The first commit also improves parsing of method declarations and fixes https://github.com/rust-lang/rust/issues/33413.
r? @eddyb
Batch of improvements to errors for new error format
This is a batch of improvements to existing errors to help get the most out of the new error format.
* Added labels to primary spans (^^^) for a set of errors that didn't currently have them
* Highlight the source blue under the secondary notes for better readability
* Move some of the "Note:" into secondary spans+labels
* Fix span_label to take &mut instead, which makes it work the same as other methods in that set
typeck: if a private field exists, also check for a public method
For example, `Vec::len` is both a field and a method, and usually encountering `vec.len` just means that the parens were forgotten.
Fixes: #26472
NOTE: I added the parameter `allow_private` to `method::exists` since I don't want to suggest inaccessible methods. For the second case, where only the method exists, I think it would make sense to set it to `false` as well, but I wanted to preserve compatibility for this case.
const_fn: Check the terminating expression of a block for blocks in a const initializer
In a const or static initializer, the `CheckBlock` check ensures that blocks in the initializer expression are only in tail positions or in items. In this case, it didn't check the terminating expression of a block, which resulted in an ICE later in the compiler pipeline if the trailing expression was itself a block. This change fixes the ICE and ensures that the proper error is emitted. This fixes the ICE in #32829 .
Add rustc_on_unimplemented for Index implementation on slice
Reopening of #31071.
It also extends the possibility of `#[rustc_on_unimplemented]` by providing a small type filter in order to find the ones which corresponds the most.
r? @pnkfelix
fix DFS for region error reporting
This was causing terrible error reports, because the algorithm was incorrectly identifying the constraints.
r? @eddyb
borrowck: do not suggest to change "&mut self" to "&mut mut self"
Matching the snippet string might not be the cleanest, but matching
the AST node instead seems to end in a lot of nested `if let`s, so I
don't know what's better.
Of course it's entirely possible that there is another API altogether
that I just don't know of?
Fixes#31424.
resolve: do not modify span of non-importable name
This span modification is probably leftover from a time when import spans were assigned differently.
With this change, error spans for the following are properly reported:
```
use abc::one_el;
use abc::{a, bbb, cccccc};
use a_very_long_name::{el, el2};
```
before (spans only):
```
x.rs:3 use abc::one_el;
^~~
x.rs:4 use abc::{a, bbb, cccccc};
^~~
x.rs:4 use abc::{a, bbb, cccccc};
^~~
x.rs:4 use abc::{a, bbb, cccccc};
^~~
(internal compiler error: unprintable span)
(internal compiler error: unprintable span)
```
after:
```
x.rs:3 use abc::one_el;
^~~~~~~~~~~
x.rs:4 use abc::{a, bbb, cccccc};
^
x.rs:4 use abc::{a, bbb, cccccc};
^~~
x.rs:4 use abc::{a, bbb, cccccc};
^~~~~~
x.rs:5 use a_very_long_name::{el, el2};
^~
x.rs:5 use a_very_long_name::{el, el2};
^~~
```
Fixes: #33464
This span modification is probably leftover from a time when
import spans were assigned differently.
With this change, error spans for the following are properly reported:
```
use abc::one_el;
use abc::{a, bbb, cccccc};
use a_very_long_name::{el, el2};
```
before (spans only):
```
x.rs:3 use abc::one_el;
^~~
x.rs:4 use abc::{a, bbb, cccccc};
^~~
x.rs:4 use abc::{a, bbb, cccccc};
^~~
x.rs:4 use abc::{a, bbb, cccccc};
^~~
(internal compiler error: unprintable span)
(internal compiler error: unprintable span)
```
after:
```
x.rs:3 use abc::one_el;
^~~~~~~~~~~
x.rs:4 use abc::{a, bbb, cccccc};
^
x.rs:4 use abc::{a, bbb, cccccc};
^~~
x.rs:4 use abc::{a, bbb, cccccc};
^~~~~~
x.rs:5 use a_very_long_name::{el, el2};
^~
x.rs:5 use a_very_long_name::{el, el2};
^~~
```
Fixes: #33464
Perform name resolution before and during ast->hir lowering
This PR performs name resolution before and during ast->hir lowering instead of in phase 3.
r? @nrc
This commit is an implementation of [RFC 1513] which allows applications to
alter the behavior of panics at compile time. A new compiler flag, `-C panic`,
is added and accepts the values `unwind` or `panic`, with the default being
`unwind`. This model affects how code is generated for the local crate, skipping
generation of landing pads with `-C panic=abort`.
[RFC 1513]: https://github.com/rust-lang/rfcs/blob/master/text/1513-less-unwinding.md
Panic implementations are then provided by crates tagged with
`#![panic_runtime]` and lazily required by crates with
`#![needs_panic_runtime]`. The panic strategy (`-C panic` value) of the panic
runtime must match the final product, and if the panic strategy is not `abort`
then the entire DAG must have the same panic strategy.
With the `-C panic=abort` strategy, users can expect a stable method to disable
generation of landing pads, improving optimization in niche scenarios,
decreasing compile time, and decreasing output binary size. With the `-C
panic=unwind` strategy users can expect the existing ability to isolate failure
in Rust code from the outside world.
Organizationally, this commit dismantles the `sys_common::unwind` module in
favor of some bits moving part of it to `libpanic_unwind` and the rest into the
`panicking` module in libstd. The custom panic runtime support is pretty similar
to the custom allocator support with the only major difference being how the
panic runtime is injected (takes the `-C panic` flag into account).
Improve diagnostics for constants being used in irrefutable patterns
It's pretty confusing and this error triggers in resolve only when "shadowing" a const, so let's make that clearer.
r? @steveklabnik
Instead of finding aux-build files in `auxiliary`, we now search for an
`aux` directory relative to the test. So if your test is
`compile-fail/foo.rs`, we would look in `compile-fail/aux`. Similarly,
we ignore the `aux` directory when searching for tets.
Short-cut `T: Sized` trait selection for ADTs
Basically avoids all nested obligations when checking whether an ADT is sized - this speeds up typeck by ~15%
The refactoring fixed#32963, but I also want to make `Copy` not object-safe (will commit that soon).
Fixes#33201
r? @nikomatsakis
This requirement appears to be missing from RFC1214, but is clearly
necessary for translation. The last field of a tuple/enum remains in
a state of limbo, compiling but causing an ICE when it is used - we
should eventually fix that somehow.
this is a [breaking-change] - a soundness fix - and requires a
crater run.
resolve: print location of static for "static in pattern" error
The implementation mirrors the one for "constant defined here" annotation used for constant patterns in the irrefutable-pattern case.
Fixes: #23716
fix various const eval errors
These were found after const_evaluating arbitrary expressions and linting if the const evaluator failed
fixes#33275 (int -> float casts for negative ints)
fixes#33291 (int -> char casts (new! wasn't allowed in constants until this PR))
r? @eddyb
cc @bluss @japaric
typeck: remove confusing suggestion for calling a fn type
* It is not clear what a "base function" is.
* The suggestion just adds parens, so suggests calling without args.
The second point could be fixed with e.g. `(...)` instead of `()`,
but the preceding "note: X is a function, perhaps you wish to call it"
should already be clear enough.
Fixes: #31341
match check: note "catchall" patterns in unreachable error
Caught as catchall patterns are:
* unconditional name bindings
* references to them
* tuple bindings with catchall elements
Fixes#31221.
resolve: improve diagnostics and lay groundwork for resolving before ast->hir
This PR improves diagnostics in `resolve` and lays some groundwork for resolving before ast->hir.
More specifically,
- It removes an API in `resolve` intended for external refactoring tools (see #27493) that appears not to be in active use. The API is incompatible with resolving before ast->hir, but could be rewritten in a more compatible and less intrusive way.
- It improves the diagnostics for pattern bindings that conflict with `const`s.
- It improves the diagnostics for modules used as expressions (fixes#33186).
- It refactors away some uses of the hir map, which is unavavailable before ast->hir lowering.
r? @eddyb
* It is not clear what a "base function" is.
* The suggestion just adds parens, so suggests calling without args.
The second point could be fixed with e.g. `(...)` instead of `()`,
but the preceding "note: X is a function, perhaps you wish to call it"
should already be clear enough.
Fixes: #31341
Feature gate clean
This PR does a bit of cleaning in the feature-gate-handling code of libsyntax. It also fixes two bugs (#32782 and #32648). Changes include:
* Change the way the existing features are declared in `feature_gate.rs`. The array of features and the `Features` struct are now defined together by a single macro. `featureck.py` has been updated accordingly. Note: there are now three different arrays for active, removed and accepted features instead of a single one with a `Status` item to tell wether a feature is active, removed, or accepted. This is mainly due to the way I implemented my macro in the first time and I can switch back to a single array if needed. But an advantage of the way it is now is that when an active feature is used, the parser only searches through the list of active features. It goes through the other arrays only if the feature is not found. I like to think that error checking (in this case, checking that an used feature is active) does not slow down compilation of valid code. :) But this is not very important...
* Feature-gate checking pass now use the `Features` structure instead of looking through a string vector. This should speed them up a bit. The construction of the `Features` struct should be faster too since it is build directly when parsing features instead of calling `has_feature` dozens of times.
* The MacroVisitor pass has been removed, it was mostly useless since the `#[cfg]-stripping` phase happens before (fixes#32648). The features that must actually be checked before expansion are now checked at the time they are used. This also allows us to check attributes that are generated by macro expansion and not visible to MacroVisitor, but are also removed by macro expansion and thus not visible to PostExpansionVisitor either. This fixes#32782. Note that in order for `#[derive_*]` to be feature-gated but still accepted when generated by `#[derive(Trait)]`, I had to do a little bit of trickery with spans that I'm not totally confident into. Please review that part carefully. (It's in `libsyntax_ext/deriving/mod.rs`.)::
Note: this is a [breaking change], since programs with feature-gated attributes on macro-generated macro invocations were not rejected before. For example:
```rust
macro_rules! bar (
() => ()
);
macro_rules! foo (
() => (
#[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps
bar!();
);
);
```
foo!();
report `const_err` on all expressions that can fail
also a drive-by fix for reporting an "overflow in shift *left*" when shifting an `i64` *right*
This increases the warning noise for shifting by more than the bitwidth and for `-T::MIN`. I can silence the bitwidth warnings explicitly and fix the const evaluator to make sure `--$expr` is treated exactly like `$expr` (which is kinda wrong, but mathematically right).
r? @eddyb
special-case #[derive(Copy, Clone)] with a shallow clone
If a type is Copy then its Clone implementation can be a no-op. Currently `#[derive(Clone)]` generates a deep clone anyway. This can lead to lots of code bloat.
This PR detects the case where Copy and Clone are both being derived (the general case of "is this type Copy" can't be determined by a syntax extension) and generates the shallow Clone impl. Right now this can only be done if there are no type parameters (see https://github.com/rust-lang/rust/issues/31085#issuecomment-178988663), but this restriction can be removed after specialization.
Fixes#31085.
Changes #[derive(Copy, Clone)] to use a faster impl of Clone when
both derives are present, and there are no generics in the type.
The faster impl is simply returning *self (which works because the
type is also Copy). See the comments in libsyntax_ext/deriving/clone.rs
for more details.
There are a few types which are Copy but not Clone, in violation
of the definition of Copy. These include large arrays and tuples. The
very existence of these types is arguably a bug, but in order for this
optimization not to change the applicability of #[derive(Copy, Clone)],
the faster Clone impl also injects calls to a new function,
core::clone::assert_receiver_is_clone, to verify that all members are
actually Clone.
This is not a breaking change, because pursuant to RFC 1521, any type
that implements Copy should not do any observable work in its Clone
impl.
Suppress fallback and ambiguity errors
If the infcx has observed other errors, then suppress both default type
parameter fallback (which can be unreliable, as the full constraint set
is not available) and errors related to unresovled
variables (annoyingly, integer type variables cannot currently be
unified with error, so that has to be a separate mechanism). Also add a
flag to `infcx` to allow us to independently indicate when we have
observed an error and hence should trigger this suppression mode.
Fixes#31997
cc @alexcrichton
r? @arielb1
syntax: Merge PathParsingMode::NoTypesAllowed and PathParsingMode::ImportPrefix
syntax: Rename PathParsingMode and its variants to better express their purpose
syntax: Remove obsolete error message about 'self lifetime
syntax: Remove ALLOW_MODULE_PATHS workaround
syntax/resolve: Adjust some error messages
resolve: Compare unhygienic (not renamed) names with keywords::Invalid, invalid identifiers may appear to be valid after renaming
This pass was supposed to check use of gated features before
`#[cfg]`-stripping but this was not the case since it in fact happens
after. Checks that are actually important and must be done before macro
expansion are now made where the features are actually used. Close#32648.
Also ensure that attributes on macro-generated macro invocations are
checked as well. Close#32782 and #32655.
This uncovered a lot of bugs in compiletest and also some shortcomings
of our existing JSON output. We had to add information to the JSON
output, such as suggested text and macro backtraces. We also had to fix
various bugs in the existing tests.
Joint work with jntrnr.
This commit adds support in rustbuild for running all of the compiletest test
suites as part of `make check`. The `compiletest` program was moved to
`src/tools` (like `rustbook` and others) and is now just compiled like any other
old tool. Each test suite has a pretty standard set of dependencies and just
tweaks various parameters to the final compiletest executable.
Note that full support is lacking in terms of:
* Once a test suite has passed, that's not remembered. When a test suite is
requested to be run, it's always run.
* The arguments to compiletest probably don't work for every possible
combination of platforms and testing environments just yet. There will likely
need to be future updates to tweak various pieces here and there.
* Cross compiled test suites probably don't work just yet, support for that will
come in a follow-up patch.
Implement `pub(restricted)` privacy (RFC 1422)
This implements `pub(restricted)` privacy from RFC 1422 (cc #32409) behind a feature gate.
`pub(restricted)` paths currently cannot use re-exported modules both for simplicity of implementation and for future compatibility with RFC 1560 (cf #31783).
r? @nikomatsakis
Fix macro hygiene bug
This fixes#32922 (EDIT: and fixes#31856), macro hygiene bugs.
It is a [breaking-change]. For example, the following would break:
```rust
fn main() {
let x = true;
macro_rules! foo { () => {
let x = 0;
macro_rules! bar { () => {x} }
let _: bool = bar!();
//^ `bar!()` used to resolve the first `x` (a bool),
//| but will now resolve to the second x (an i32).
}}
foo! {};
}
```
r? @nrc
don't report errors in constants at every use site
partially fixes#32842
r? @arielb1
cc @retep998
I chose this way of implementing it, because the alternative (checking if the error span is inside the constant's expressions's span) would get confusing when combined with expression generating macros.
A next step would be to re-enable the re-reporting of errors if the original erroneous constant is in another crate.
Replace consider_unification_despite_ambiguity with new obligation variant
Is work towards #32730. Addresses part one of #32286. Addresses #24210 and #26046 to some degree.
r? @nikomatsakis
resolve: Improve duplicate glob detection
This fixes a bug introduced in #31726 in which we erroneously allow multiple imports of the same item under some circumstances.
More specifically, we erroneously allow a module that is in a cycle of glob re-exports to have other re-exports (besides the glob from the cycle).
For example,
```rust
pub fn f() {}
mod foo {
pub use f; // (1) This defines `foo::f`.
pub use bar::*; // (3) This also defines `foo::f`, which should be a duplicate error but is currently allowed.
}
mod bar {
pub use foo::*; // (2) This defines `bar::f`.
}
```
A module in a glob re-export cycle can still have `pub` items after this PR. For example,
```rust
mod foo {
pub fn f() {}; // (1) This defines `foo::f`.
pub use bar::*; // (3) This is not a duplicate error since items shadow glob-imported re-exports (cf #31337).
}
mod bar {
pub use foo::*; // (2) This defines `bar::f`.
}
```
r? @nikomatsakis
If the infcx has observed other errors, then suppress both default type
parameter fallback (which can be unreliable, as the full constraint set
is not available) and errors related to unresovled
variables (annoyingly, integer type variables cannot currently be
unified with error, so that has to be a separate mechanism). Also add a
flag to `infcx` to allow us to independently indicate when we have
observed an error and hence should trigger this suppression mode.
This commit rewrites all of the tidy checks we have, namely:
* featureck
* errorck
* tidy
* binaries
into Rust under a new `tidy` tool inside of the `src/tools` directory. This at
the same time deletes all the corresponding Python tidy checks so we can be sure
to only have one source of truth for all the tidy checks.
cc #31590
std: Stabilize APIs for the 1.9 release
This commit applies all stabilizations, renamings, and deprecations that the
library team has decided on for the upcoming 1.9 release. All tracking issues
have gone through a cycle-long "final comment period" and the specific APIs
stabilized/deprecated are:
Stable
* `std::panic`
* `std::panic::catch_unwind` (renamed from `recover`)
* `std::panic::resume_unwind` (renamed from `propagate`)
* `std::panic::AssertUnwindSafe` (renamed from `AssertRecoverSafe`)
* `std::panic::UnwindSafe` (renamed from `RecoverSafe`)
* `str::is_char_boundary`
* `<*const T>::as_ref`
* `<*mut T>::as_ref`
* `<*mut T>::as_mut`
* `AsciiExt::make_ascii_uppercase`
* `AsciiExt::make_ascii_lowercase`
* `char::decode_utf16`
* `char::DecodeUtf16`
* `char::DecodeUtf16Error`
* `char::DecodeUtf16Error::unpaired_surrogate`
* `BTreeSet::take`
* `BTreeSet::replace`
* `BTreeSet::get`
* `HashSet::take`
* `HashSet::replace`
* `HashSet::get`
* `OsString::with_capacity`
* `OsString::clear`
* `OsString::capacity`
* `OsString::reserve`
* `OsString::reserve_exact`
* `OsStr::is_empty`
* `OsStr::len`
* `std::os::unix::thread`
* `RawPthread`
* `JoinHandleExt`
* `JoinHandleExt::as_pthread_t`
* `JoinHandleExt::into_pthread_t`
* `HashSet::hasher`
* `HashMap::hasher`
* `CommandExt::exec`
* `File::try_clone`
* `SocketAddr::set_ip`
* `SocketAddr::set_port`
* `SocketAddrV4::set_ip`
* `SocketAddrV4::set_port`
* `SocketAddrV6::set_ip`
* `SocketAddrV6::set_port`
* `SocketAddrV6::set_flowinfo`
* `SocketAddrV6::set_scope_id`
* `<[T]>::copy_from_slice`
* `ptr::read_volatile`
* `ptr::write_volatile`
* The `#[deprecated]` attribute
* `OpenOptions::create_new`
Deprecated
* `std::raw::Slice` - use raw parts of `slice` module instead
* `std::raw::Repr` - use raw parts of `slice` module instead
* `str::char_range_at` - use slicing plus `chars()` plus `len_utf8`
* `str::char_range_at_reverse` - use slicing plus `chars().rev()` plus `len_utf8`
* `str::char_at` - use slicing plus `chars()`
* `str::char_at_reverse` - use slicing plus `chars().rev()`
* `str::slice_shift_char` - use `chars()` plus `Chars::as_str`
* `CommandExt::session_leader` - use `before_exec` instead.
Closes#27719
cc #27751 (deprecating the `Slice` bits)
Closes#27754Closes#27780Closes#27809Closes#27811Closes#27830Closes#28050Closes#29453Closes#29791Closes#29935Closes#30014Closes#30752Closes#31262
cc #31398 (still need to deal with `before_exec`)
Closes#31405Closes#31572Closes#31755Closes#31756
This commit applies all stabilizations, renamings, and deprecations that the
library team has decided on for the upcoming 1.9 release. All tracking issues
have gone through a cycle-long "final comment period" and the specific APIs
stabilized/deprecated are:
Stable
* `std::panic`
* `std::panic::catch_unwind` (renamed from `recover`)
* `std::panic::resume_unwind` (renamed from `propagate`)
* `std::panic::AssertUnwindSafe` (renamed from `AssertRecoverSafe`)
* `std::panic::UnwindSafe` (renamed from `RecoverSafe`)
* `str::is_char_boundary`
* `<*const T>::as_ref`
* `<*mut T>::as_ref`
* `<*mut T>::as_mut`
* `AsciiExt::make_ascii_uppercase`
* `AsciiExt::make_ascii_lowercase`
* `char::decode_utf16`
* `char::DecodeUtf16`
* `char::DecodeUtf16Error`
* `char::DecodeUtf16Error::unpaired_surrogate`
* `BTreeSet::take`
* `BTreeSet::replace`
* `BTreeSet::get`
* `HashSet::take`
* `HashSet::replace`
* `HashSet::get`
* `OsString::with_capacity`
* `OsString::clear`
* `OsString::capacity`
* `OsString::reserve`
* `OsString::reserve_exact`
* `OsStr::is_empty`
* `OsStr::len`
* `std::os::unix::thread`
* `RawPthread`
* `JoinHandleExt`
* `JoinHandleExt::as_pthread_t`
* `JoinHandleExt::into_pthread_t`
* `HashSet::hasher`
* `HashMap::hasher`
* `CommandExt::exec`
* `File::try_clone`
* `SocketAddr::set_ip`
* `SocketAddr::set_port`
* `SocketAddrV4::set_ip`
* `SocketAddrV4::set_port`
* `SocketAddrV6::set_ip`
* `SocketAddrV6::set_port`
* `SocketAddrV6::set_flowinfo`
* `SocketAddrV6::set_scope_id`
* `<[T]>::copy_from_slice`
* `ptr::read_volatile`
* `ptr::write_volatile`
* The `#[deprecated]` attribute
* `OpenOptions::create_new`
Deprecated
* `std::raw::Slice` - use raw parts of `slice` module instead
* `std::raw::Repr` - use raw parts of `slice` module instead
* `str::char_range_at` - use slicing plus `chars()` plus `len_utf8`
* `str::char_range_at_reverse` - use slicing plus `chars().rev()` plus `len_utf8`
* `str::char_at` - use slicing plus `chars()`
* `str::char_at_reverse` - use slicing plus `chars().rev()`
* `str::slice_shift_char` - use `chars()` plus `Chars::as_str`
* `CommandExt::session_leader` - use `before_exec` instead.
Closes#27719
cc #27751 (deprecating the `Slice` bits)
Closes#27754Closes#27780Closes#27809Closes#27811Closes#27830Closes#28050Closes#29453Closes#29791Closes#29935Closes#30014Closes#30752Closes#31262
cc #31398 (still need to deal with `before_exec`)
Closes#31405Closes#31572Closes#31755Closes#31756
Save/load incremental compilation dep graph
Contains the code to serialize/deserialize the dep graph to disk between executions. We also hash the item contents and compare to the new hashes. Also includes a unit test harness. There are definitely some known limitations, such as https://github.com/rust-lang/rust/issues/32014 and https://github.com/rust-lang/rust/issues/32015, but I am leaving those for follow-up work.
Note that this PR builds on https://github.com/rust-lang/rust/pull/32007, so the overlapping commits can be excluded from review.
r? @michaelwoerister
Lay groundwork for RFC 1422 and improve `PrivateItemsInPublicInterfacesVisitor`
This PR lays groundwork for RFC 1422 (cc #32409) and improves `PrivateItemsInPublicInterfacesVisitor`. More specifically, it
- Refactors away `hir::Visibility::inherit_from`, the semantics of which are obsolete.
- Makes `hir::Visibility` non-`Copy` so that we will be able to add new variants to represent `pub(restricted)` (for example, `Visibility::Restricted(Path)`).
- Adds a new `Copy` type `ty::Visibility` that represents a visibility value, i.e. a characterization of where an item is accessible. This is able to represent `pub(restricted)` visibilities.
- Improves `PrivateItemsInPublicInterfacesVisitor` so that it checks for items in an interface that are less visible than the interface. This fixes#30079 but doesn't change any other behavior.
r? @nikomatsakis
Suggest adding a where-clause when that can help
Suggest adding a where-clause when there is an unmet trait-bound that can be satisfied if some type can implement it.
r? @nikomatsakis
Fix LLVM assert when handling bad intrinsic monomorphizations
Passing an invalid type to certain intrinsics would trigger an LLVM assert even though the invalid type was caught by the compiler.
r? @eddyb
You can now pass `-Z incremental=dir` as well as saying `-Z
query-dep-graph` if you want to enable queries for some other
purpose. Accessor functions take the place of computed boolean flags.
Fix "consider removing this semicolon" help
Check last statement in a block, not the first.
Example of current weirdness: http://is.gd/w80J9h
The help was only rarely emitted, and if so, often incorrectly (see above playpen). It was basically only useful with single-statement functions.
Fix issue: Global paths in `use` directives can begin with `super` or `self` #32225
This PR fixes#32225 by warning on `use ::super::...` and `use ::self::...` on `resolve`.
Current changes is the most minimal and ad-hoc.
resolve: Improve import failure detection and lay groundwork for RFC 1422
This PR improves import failure detection and lays some groundwork for RFC 1422.
More specifically, it
- Avoids recomputing the resolution of an import directive's module path.
- Refactors code in `resolve_imports` that does not scale to the arbitrarily many levels of visibility that will be required by RFC 1422.
- Replaces `ModuleS`'s fields `public_glob_count`, `private_glob_count`, and `resolved_globs` with a list of glob import directives `globs`.
- Replaces `NameResolution`'s fields `pub_outstanding_references` and `outstanding_references` with a field `single_imports` of a newly defined type `SingleImports`.
- Improves import failure detection by detecting cycles that include single imports (currently, only cycles of globs are detected). This fixes#32119.
r? @nikomatsakis
Only allow using the atomic intrinsics on integer types
Using these with non-integer types results in LLVM asserts. Atomic operations on non-integer types will require values be transmuted into an integer type of suitable size.
This doesn't affect the standard library since `AtomicBool` and `AtomicPtr` currently use `usize` for atomic operations.
r? @eddyb
When deciding on a coinductive match, we were examining the new
obligation and the backtrace, but not the *current* obligation that goes
in between the two. Refactoring the code to just have the cycle given
as input also made things a lot simpler.
Integrate privacy into field and method selection
This PR integrates privacy checking into field and method selection so that an inaccessible field/method can not stop an accessible field/method from being used (fixes#12808 and fixes#22684).
r? @eddyb
diagnostics: make paths to external items more visible
This PR changes the reported path for an external item so that it is visible from at least one local module (i.e. it does not use any inaccessible external modules) if possible. If the external item's crate was declared with an `extern crate`, the path is guarenteed to use the `extern crate`.
Fixes#23224, fixes#23355, fixes#26635, fixes#27165.
r? @nrc
Gate parser recovery via debugflag
Gate parser recovery via debugflag
Put in `-Z continue_parse_after_error`
This works by adding a method, `fn abort_if_no_parse_recovery`, to the
diagnostic handler in `syntax::errors`, and calling it after each
error is emitted in the parser.
(We might consider adding a debugflag to do such aborts in other
places where we are currently attempting recovery, such as resolve,
but I think the parser is the really important case to handle in the
face of #31994 and the parser bugs of varying degrees that were
injected by parse error recovery.)
r? @nikomatsakis
parser recovery (so that expected errors match up)
I'm opting into parser recovery in all these cases out of expediency,
not because the error messages you get with recovery enabled are
actually all that usable in all cases listed.
Prevent bumping the parser past the EOF.
Makes `Parser::bump` after EOF into an ICE, forcing callers to avoid repeated EOF bumps.
This ICE is intended to break infinite loops where EOF wasn't stopping the loop.
For example, the handling of EOF in `parse_trait_items`' recovery loop fixes#32446.
But even without this specific fix, the ICE is triggered, which helps diagnosis and UX.
This is a `[breaking-change]` for plugins authors who eagerly eat multiple EOFs.
See https://github.com/docopt/docopt.rs/pull/171 for such an example and the necessary fix.
melt the ICE when lowering an impossible range
Emit a fatal error instead of panicking when HIR lowering encounters a range with no `end` point.
This involved adding a method to wire up `LoweringContext::span_fatal`.
Fixes#32245 (cc @nodakai).
r? @nrc
Restrict constants in patterns
This implements [RFC 1445](https://github.com/rust-lang/rfcs/blob/master/text/1445-restrict-constants-in-patterns.md). The primary change is to limit the types of constants used in patterns to those that *derive* `Eq` (note that implementing `Eq` is not sufficient). This has two main effects:
1. Floating point constants are linted, and will eventually be disallowed. This is because floating point constants do not implement `Eq` but only `PartialEq`. This check replaces the existing special case code that aimed to detect the use of `NaN`.
2. Structs and enums must derive `Eq` to be usable within a match.
This is a [breaking-change]: if you encounter a problem, you are most likely using a constant in an expression where the type of the constant is some struct that does not currently implement
`Eq`. Something like the following:
```rust
struct SomeType { ... }
const SOME_CONST: SomeType = ...;
match foo {
SOME_CONST => ...
}
```
The easiest and most future compatible fix is to annotate the type in question with `#[derive(Eq)]` (note that merely *implementing* `Eq` is not enough, it must be *derived*):
```rust
struct SomeType { ... }
const SOME_CONST: SomeType = ...;
match foo {
SOME_CONST => ...
}
```
Another good option is to rewrite the match arm to use an `if` condition (this is also particularly good for floating point types, which implement `PartialEq` but not `Eq`):
```rust
match foo {
c if c == SOME_CONST => ...
}
```
Finally, a third alternative is to tag the type with `#[structural_match]`; but this is not recommended, as the attribute is never expected to be stabilized. Please see RFC #1445 for more details.
cc https://github.com/rust-lang/rust/issues/31434
r? @pnkfelix
resolve: Minimize hacks in name resolution of primitive types
When resolving the first unqualified segment in a path with `n` segments and `n - 1` associated item segments, e.g. (`a` or `a::assoc` or `a::assoc::assoc` etc) try to resolve `a` without considering primitive types first. If the "normal" lookup fails or results in a module, then try to resolve `a` as a primitive type as a fallback.
This way backward compatibility is respected, but the restriction from E0317 can be lifted, i.e. primitive names mostly can be shadowed like any other names.
Furthermore, if names of primitive types are [put into prelude](https://github.com/petrochenkov/rust/tree/prim2) (now it's possible to do), then most of names will be resolved in conventional way and amount of code relying on this fallback will be greatly reduced. Although, it's not entirely convenient to put them into prelude right now due to temporary conflicts like `use prelude::v1::*; use usize;` in libcore/libstd, I'd better wait for proper glob shadowing before doing it.
I wish the `no_prelude` attribute were unstable as intended :(
cc @jseyfried @arielb1
r? @eddyb
Disallow methods from traits that are not in scope
This PR only allows a trait method to be used if the trait is in scope (fixes#31379).
This is a [breaking-change]. For example, the following would break:
```rust
mod foo {
pub trait T { fn f(&self) {} }
impl T for () {}
}
mod bar { pub use foo::T; }
fn main() {
pub use bar::*;
struct T; // This shadows the trait `T`,
().f() // making this an error.
}
```
r? @nikomatsakis
Alter E0412 help message wording
The initial wording does not make sense due to an extra 'to'.
There are two potential candidates we can change this to:
- 'you can import it into scope'
- 'to import it into scope'
In keeping the changes minimal, we choose the first, as this is more in line with the grammar of the extended candidates help message.
The older code would sometimes swallow errors or fail to produce a
suggestion. The newer code does not. However, just printing everything
would produce a bunch of new and kind of annoying errors, so continue
to swallow `T: 'a` errors so long as there are other things to show.
Refactor call & function handling in trans, enable MIR bootstrap.
Non-Rust and Rust ABIs were combined into a common codepath, which means:
* The ugly `__rust_abi` "clown shoes" shim for C->Rust FFI is gone, fixes#10116.
* Methods, *including virtual ones* support non-Rust ABIs, closes#30235.
* Non-Rust ABIs also pass fat pointers in two arguments; the result should be identical.
* Zero-sized types are never passed as arguments; again, behavior shouldn't change.
Additionally, MIR support for calling intrinsics (through old trans) was implemented.
Alongside assorted fixes, it enabled MIR to launch 🚀 and do a *complete* bootstrap.
To try it yourself, `./configure --enable-orbit` *or* `make RUSTFLAGS="-Z orbit"`.
Original issue: https://github.com/rust-lang/rust/issues/21195
Relevant PR: https://github.com/rust-lang/rust/pull/30778
Prior to this commit, if a compiletest testcase included the text
"HELP:" or "NOTE:" (note the colons), then it would indicate to the
compiletest suite that we should verify "help" and "note" expected
messages.
This commit updates this check to also check "HELP" and "NOTE" (not the
absense of colons) so that we always verify "help" and "note" expected
messages.
Resolve: improve diagnostics for duplicate definitions and imports
This PR improves and regularizes the diagnostics for duplicate definitions and imports.
After this PR, the second of two duplicate definitions/imports will have the following form:
> a(n) [value|type|module|trait|extern crate] named \`*name*\` has already been [defined|imported] in this [module|block|trait|enum]
with a note referencing this first of the two duplicate definitions/imports:
> previous [definition|import] of \`*name*\` here
The error indices remain unchanged.
r? @eddyb
projection sensitive to "mode" (most importantly, trans vs middle).
This commit introduces several pieces of iteration infrastructure in the
specialization graph data structure, as well as various helpers for
finding the definition of a given item, given its kind and name.
In addition, associated type projection is now *mode-sensitive*, with
three possible modes:
- **Topmost**. This means that projection is only possible if there is a
non-`default` definition of the associated type directly on the
selected impl. This mode is a bit of a hack: it's used during early
coherence checking before we have built the specialization
graph (and therefore before we can walk up the specialization
parents to find other definitions). Eventually, this should be
replaced with a less "staged" construction of the specialization
graph.
- **AnyFinal**. Projection succeeds for any non-`default` associated
type definition, even if it is defined by a parent impl. Used
throughout typechecking.
- **Any**. Projection always succeeds. Used by trans.
The lasting distinction here is between `AnyFinal` and `Any` -- we wish
to treat `default` associated types opaquely for typechecking purposes.
In addition to the above, the commit includes a few other minor review fixes.