Ban registering obligations during InferCtxt snapshots.
Back in #33852, a flag was added to `InferCtxt` to prevent rolling back a snapshot if obligations were added to some `FulfillmentContext` during the snapshot, to prevent leaking fresh inference variables (created during that snapshot, so their indices would get reused) in obligations, which could ICE or worse.
But that isn't enough in the long run, as type-checking ends up relying on success implying that eager side-effects are fine, and while stray obligations *do* get caught nowadays, those errors prevent, e.g. the speculative coercions from #37658, which *have to* be rolled back *even* if they succeed.
We can't just allow those obligations to stay around though, because we end up, again, in ICEs or worse.
Instead, this PR modifies `lookup_method_in_trait_adjusted` to return `InferOk` containing the obligations that `Autoderef::finalize_as_infer_ok` can propagate to deref coercions.
As there shouldn't be *anything* left that registers obligations during snapshots, it's completely banned.
r? @nikomatsakis @arielb1
Move E0101 and E0102 logic into new E0282 mechanism #40013
Hello there!
## What's this?
Previously, me and @nikomatsakis worked on error messages of uninferred locals. (#38812)
This aims to build up on that by moving certain type checks from `writeback`.
With this, `E0101` and `E0102` errors are getting obsoleted and no longer thrown.
They're replaced with customized versions of `E0282`s instead.
## Sample Error Messages
#### `E0101` is getting converted into:
```rust
error[E0282]: type annotations needed
--> test.rs:2:14
|
2 | let x = |_| {};
| ^ consider giving this closure parameter a type
error: aborting due to previous error
```
#### `E0102` is getting converted into:
```rust
error[E0282]: type annotations needed
--> test.rs:2:9
|
2 | let x = [];
| ^
| |
| consider giving `x` a type
| cannot infer type for `[_; 0]`
error: aborting due to previous error
```
## Annoyances
- I think we need to change our way of type name resolving in relevant places, because that `[_; 0]` looks horrible IMHO.
- I'm not terribly happy with the note ordering of errors. So please do point to code that might help me accomplish this.
## Tests
Tests of `E0101` and `E0102` are getting converted from `compile-fail` to `ui` tests.
## Documentation
Please help me with documentation update. There are some confusing places that needed an update but I'm not sure if I did the right ones.
Please do comment on messages, layouts and other details.
## Appreciation
Huge thanks goes to @nikomatsakis for being a patient and humble mentor along this long journey. 🍻
We no longer need to track the tasks in these cases since these
particular tasks have no outputs (except, potentially, errors...) and
they always execute.
[on-demand] Turn monomorphic_const_eval into a proper query, not just a cache.
The error definitions and reporting logic, alongside with `eval_length` were moved to `librustc`.
Both local and cross-crate constant evaluation is on-demand now, but the latter is only used for `enum` discriminants, to replace the manual insertion into the cache which was done when decoding variants.
r? @nikomatsakis
rustc: provide adt_sized_constraint as an on-demand query.
By using `queries::adt_sized_constraint::try_get`, we can detect cycles without a separate stack.
r? @nikomatsakis
add 'mir' to rustc help menu and man doc
add 'mir' to '--emit' flag list for 'rustc'.
This is added because 'rustc' can now generate MIR (referencing to
"Teach rustc --emit=mir #39891").
Do not desugar if-let-else to match arm guards
Fixes#41272
Changed the desugaring code
**Before**
```rust
match <sub_expr> {
<pat> => <body>,
[_ if <else_opt_if_cond> => <else_opt_if_body>,]
_ => [<else_opt> | ()]
}
```
**After**
```rust
match <sub_expr> {
<pat> => <body>,
_ => [<else_opt> | ()]
}
```
With this fix, it doesn't cause E0301
I've added some explicit tests that negative impls are allowed to
overlap, and also to make sure that the feature doesn't interfere with
specialization. I've not added an explicit test for positive overlapping
with negative, as that's already tested elsewhere.
This patch allows overlap to occur between any two impls of a trait for
traits which have no associated items.
Several compile-fail tests around coherence had to be changed to add at
least one item to the trait they test against.
Ref #29864
Implement global_asm!() (RFC 1548)
This is a first attempt. ~~One (potential) problem I haven't solved is how to handle multiple usages of `global_asm!` in a module/crate. It looks like `LLVMSetModuleInlineAsm` overwrites module asm, and `LLVMAppendModuleInlineAsm` is not provided in LLVM C headers 😦~~
I can provide more detail as needed, but honestly, there's not a lot going on here.
r? @eddyb
CC @Amanieu @jackpot51
Tracking issue: #35119
Miscellneous refactorings of trans
This doesn't achieve any particular goal yet, but it's a collection of refactorings with the common goal of turning `SharedCrateContext` etc into stuff that we can use with on-demand and actually expect to hash in a stable fashion for incremental. Not there yet, clearly.
r? @eddyb
cc @michaelwoerister
rustc_typeck: consolidate adjustment composition
Instead of having `write_adjustment` overwrite the previous adjustment, have `apply_adjustment` compose a new adjustment on top of the previous one. This is important because `NeverToAny` adjustments can be present on expressions during coercion.
Fixes#41213.
r? @nikomatsakis
A number of things were using `crate_hash` that really ought to be using
`crate_disambiguator` (e.g., to create the plugin symbol names). They
have been updated.
It is important to remove `LinkMeta` from `SharedCrateContext` since it
contains a hash of the entire crate, and hence it will change
whenever **anything** changes (which would then require
rebuilding **everything**).
Windows builder croaked. This change tries to fix that by actually
calling the global_asm-defined function so the symbol doesn't get
optimized away, if that is in fact what was happening.
Additionally, we provide an empty main() for non-x86 arches.
Handle subtyping in inference through obligations
We currently store subtyping relations in the `TypeVariables` structure as a kind of special case. This branch uses normal obligations to propagate subtyping, thus converting our inference variables into normal fallback. It also does a few other things:
- Removes the (unstable, outdated) support for custom type inference fallback.
- It's not clear how we want this to work, but we know that we don't want it to work the way it currently does.
- The existing support was also just getting in my way.
- Fixes#30225, which was caused by the trait caching code pretending type variables were normal unification variables, when indeed they were not (but now are).
There is one fishy part of these changes: when computing the LUB/GLB of a "bivariant" type parameter, I currently return the `a` value. Bivariant type parameters are only allowed in a very particular situation, where the type parameter is only used as an associated type output, like this:
```rust
pub struct Foo<A, B>
where A: Fn() -> B
{
data: A
}
```
In principle, if one had `T=Foo<A, &'a u32>` and `U=Foo<A, &'b u32>` and (e.g.) `A: for<'a> Fn() -> &'a u32`, then I think that computing the LUB of `T` and `U` might do the wrong thing. Probably the right behavior is just to create a fresh type variable. However, that particular example would not compile (because the where-clause is illegal; `'a` does not appear in any input type). I was not able to make an example that *would* compile and demonstrate this shortcoming, and handling the LUB/GLB was mildly inconvenient, so I left it as is. I am considering whether to revisit this or what.
I have started a crater run to test the impact of these changes.
Travis failures indicated the OuterVisitor#visit_item method caused a
panic. The Visitor's inner visitor actually relies on the visitor
visiting every item's NodeId. I forgot to perform that call in the
ItemGlobalAsm match arm, leading to build breakage. The fix is
simple: call visit_id(...) for ItemGlobalAsm
Highlight and simplify mismatched types
Shorten mismatched types errors by replacing subtypes that are not
different with `_`, and highlighting only the subtypes that are
different.
Given a file
```rust
struct X<T1, T2> {
x: T1,
y: T2,
}
fn foo() -> X<X<String, String>, String> {
X { x: X {x: "".to_string(), y: 2}, y: "".to_string()}
}
fn bar() -> Option<String> {
"".to_string()
}
```
provide the following output
```rust
error[E0308]: mismatched types
--> file.rs:6:5
|
6 | X { x: X {x: "".to_string(), y: 2}, y: "".to_string()}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found {integer}
|
= note: expected type `X<X<_, std::string::String>, _>`
^^^^^^^^^^^^^^^^^^^ // < highlighted
found type `X<X<_, {integer}>, _>`
^^^^^^^^^ // < highlighted
error[E0308]: mismatched types
--> file.rs:6:5
|
10 | "".to_string()
| ^^^^^^^^^^^^^^ expected struct `std::option::Option`, found `std::string::String`
|
= note: expected type `Option<std::string::String>`
^^^^^^^ ^ // < highlighted
found type `std::string::String`
```
Fix#21025. Re: #40186. Follow up to #39906.
I'm looking to change how this output is accomplished so that it doesn't create list of strings to pass around, but rather add an elided `Ty` placeholder, and use the same string formatting for normal types. I'll be doing that soonish.
r? @nikomatsakis
ICH: Replace old, transitive metadata hashing with direct hashing approach.
This PR replaces the old crate metadata hashing strategy with a new one that directly (but stably) hashes all values we encode into the metadata. Previously we would track what data got accessed during metadata encoding and then hash the input nodes (HIR and upstream metadata) that were transitively reachable from the accessed data. While this strategy was sound, it had two major downsides:
1. It was susceptible to generating false positives, i.e. some input node might have changed without actually affecting the content of the metadata. That metadata entry would still show up as changed.
2. It was susceptible to quadratic blow-up when many metadata nodes shared the same input nodes, which would then get hashed over and over again.
The new method does not have these disadvantages and it's also a first step towards caching more intermediate results in the compiler.
Metadata hashing/cross-crate incremental compilation is still kept behind the `-Zincremental-cc` flag even after this PR. Once the new method has proven itself with more tests, we can remove the flag and enable cross-crate support by default again.
r? @nikomatsakis
cc @rust-lang/compiler
remove unnecessary tasks
Remove various unnecessary tasks. All of these are "always execute" tasks that don't do any writes to tracked state (or else an assert would trigger, anyhow). In some cases, they issue lints or errors, but we''ll deal with that -- and anyway side-effects outside of a task don't cause problems for anything that I can see.
The one non-trivial refactoring here is the borrowck conversion, which adds the requirement to go from a `DefId` to a `BodyId`. I tried to make a useful helper here.
r? @eddyb
cc #40746
cc @cramertj @michaelwoerister
Instead of collecting all potential inputs to some metadata entry and
hashing those, we directly hash the values we are storing in metadata.
This is more accurate and doesn't suffer from quadratic blow-up when
many entries have the same dependencies.