Don't visit foreign function bodies when lowering ast to hir
Previously the existence of bodies inside a foreign function block would
cause a panic in the hir `NodeCollector` during its collection of crate
bodies to compute a crate hash:
e59b08e62e/src/librustc_middle/hir/map/collector.rs (L154-L158)
The collector walks the hir tree and creates a map of hir nodes, then
attaching bodies in the crate to their owner in the map. For a code like
```rust
extern "C" {
fn f() {
fn g() {}
}
}
```
The crate bodies include the body of the function `g`. But foreign
functions cannot have bodies, and while the parser AST permits a foreign
function to have a body, the hir doesn't. This means that the body of
`f` is not present in the hir, and so neither is `g`. So when the
`NodeCollector` finishes the walking the hir, it has no record of `g`,
cannot find an owner for the body of `g` it sees in the crate bodies,
and blows up.
Why do the crate bodies include the body of `g`? The AST walker has a
need a for walking function bodies, and FFIs share the same AST node as
functions in other contexts.
There are at least two options to fix this:
- Don't unwrap the map entry for an hir node in the `NodeCollector`
- Modifier the ast->hir lowering visitor to ignore foreign function
blocks
I don't think the first is preferrable, since we want to know when we
can't find a body for an hir node that we thought had one (dropping this
information may lead to an invalid hash). So this commit implements the
second option.
Closes#74120
polymorphize: `I` used if `T` used in `I: Foo<T>`
Fixes#75326.
This PR adjusts polymorphization's handling of predicates so that after ensuring that `T` is used in `I: Foo<T>` if `I` is used, it now ensures that `I` is used if `T` is used in `I: Foo<T>`. This is necessary to mark generic parameters that only exist in impl parameters as used - thereby avoiding symbol clashes when using the new mangling scheme.
With this PR, rustc will now fully bootstrap with polymorphization and the new symbol mangling scheme enabled - not all tests pass, but I'm not sure how much of that is the interaction of the two features, I'll be looking into that soon. All tests pass with only polymorphization enabled.
r? @lcnr (this isn't sufficiently complex that I need to add to eddy's review queue)
cc @eddyb
Recover gracefully from `struct` parse errors
Currently the parser tries to recover from finding a keyword where a field name was expected, but this causes extra knock down parse errors that are completely irrelevant. Instead, bail out early in the parsing of the field and consume the remaining tokens in the block. This can reduce output significantly.
_Improvements based on the narrative in https://fasterthanli.me/articles/i-am-a-java-csharp-c-or-cplusplus-dev-time-to-do-some-rust_
Remove most specialization use in serialization
Switching from specialization to min_specialization in the compiler made the unsoundness of how we used these traits pretty clear. This changes how the `Encodable` and `Decodable` traits work to be more friendly for types need a `TyCtxt` to deserialize.
The alternative design of having both `Encodable` and `TyEncodable` traits was considered, but doesn't really work because the following impls would conflict:
```
impl<E: Ecodable> TyEncodable for Encodable
impl<E: TyEcodable> TyEncodable for [E]
```
## How-to guide
- `Rustc(De|En)codable` is now spelled `Ty(De|En)coable` in `rustc_middle`, `Metadata(En|De)codable` in `rustc_metadata` where needed, and `(De|En)codable` everywhere else.
- Manual implementations of `(De|En)codable` shouldn't be much different.
- If you're adding a new interned type that needs to be en/decodable then the simplest thing way to handle this is:
- Have the type be a wrapper around a reference to the interned data (i.e. do what `ty::Predicate` does, and not what all of the other interned types do)
- Derive `Ty(En|De)codable` on the inner type
- Implement `Encodable<impl TyEncoder>` by forwarding to the inner type.
- Implement `Decodable<impl TyDecoder>` by decoding the inner type and then creating the wrapper around that (using the `tcx` from the decoder as needed).
cc @rust-lang/compiler for opinions on this change
r? @oli-obk
This commit adjusts polymorphization's handling of predicates so that
after ensuring that `T` is used in `I: Foo<T>` if `I` is used, it now
ensures that `I` is used if `T` is used in `I: Foo<T>`. This is
necessary to mark generic parameters that only exist in impl parameters
as used - thereby avoiding symbol clashes when using the new mangling
scheme.
Signed-off-by: David Wood <david@davidtw.co>
Do not emit E0228 when it is implied by E0106
Emit E0288 (lifetime bound for trait object cannot be deduced) only on bare trait objects. When the trait object is in the form of `&dyn Trait`, E0106 (missing lifetime specifier) will have been emitted, making the former redundant.
Emit E0288 (lifetime bound for trait object cannot be deduced) only on
bare trait objects. When the trait object is in the form of
`&dyn Trait`, E0106 (missing lifetime specifier) will have been emitted,
making the former redundant.
Change registered "program name" for -Cllvm-args usage messages
While debugging a codegen issue, I tried adding LLVM options with
the rustc -Cllvm-args option, and was confused by the error and usage
messaging.
The LLVM "program name" argument is set to "rustc", and command line
error messages make it look like invalid arguments are "rustc"
arguments, not LLVM.
I changed this argument so error messages and the "-help" usage feedback
is easier to understand and react to. (Clang does something similar.)
r? @wesleywiser
Add a bunch of const-generic revisions for `min_const_generics`
This adds a bunch of revisions to `const-generic` tests which is part of #75279, but doesn't cover everything.
r? @lcnr
Fix suggestion to use lifetime in type and in assoc const
_Do not merge until #75363 has landed, as it has the test case for this._
* Account for associated types
* Associated `const`s can't have generics (fix#74264)
* Do not suggest duplicate lifetimes and suggest `for<'a>` more (fix#72404)
While debugging a codegen issue, I tried adding LLVM options with
the rustc -Cllvm-args option, and was confused by the error and usage
messaging.
The LLVM "program name" argument is set to "rustc", and command line
error messages make it look like invalid arguments are "rustc"
arguments, not LLVM.
I changed this argument so error messages and the "-help" usage feedback
is easier to understand and react to. (Clang does something similar.)
Miri: improve spans of required_const failures
In https://github.com/rust-lang/rust/pull/75339 I added a loop evaluating all consts required by a function body. Unfortunately, if one of their evaluations fails, then the span used for that was that of the first statement in the function body, which happened to work form some existing test but is not sensible in general.
This PR changes it to point to the whole function instead, which is at least not wrong.
r? @oli-obk
Fix regionck failure when converting Index to IndexMut
Fixes#74933
Consider an overloaded index expression `base[index]`. Without knowing whether it will be mutated, this will initially be desugared into `<U as Index<T>>::index(&base, index)` for some `U` and `T`. Let `V` be the `expr_ty_adjusted` of `index`.
If this expression ends up being used in any mutable context (or used in a function call with `&mut self` receiver before #72280), we will need to fix it up. The current code will rewrite it to `<U as IndexMut<V>>::index_mut(&mut base, index)`. In most cases this is fine as `V` will be equal to `T`, however this is not always true when `V/T` are references, as they may have different region.
This issue is quite subtle before #72280 as this code path is only used to fixup function receivers, but after #72280 we've made this a common path.
The solution is basically just rewrite it to `<U as IndexMut<T>>::index_mut(&mut base, index)`. `T` can retrieved in the fixup path using `node_substs`.
Reland #74069
Investigation in #74716 has concluded that this PR is indeed not a regression (and in fact the rollup itself is not either).
This reverts the revert in #74611.
r? @nnethercote cc @eddyb
Tweak conditions for E0026 and E0769
When we have a tuple struct used with struct we don't want to suggest using the (valid) struct syntax with numeric field names. Instead we want to suggest the expected syntax.
Given
```rust
fn main() {
match MyOption::MySome(42) {
MyOption::MySome { x: 42 } => (),
_ => (),
}
}
```
We now emit E0769 "tuple variant `MyOption::MySome` written as struct variant" instead of E0026 "variant `MyOption::MySome` does not have a field named `x`".
polymorphize: constrain unevaluated const handling
This PR constrains the support added for handling unevaluated consts in polymorphization (introduced in #75260) by:
- Skipping associated constants as this causes cycle errors.
- Skipping promoted constants when they contain `Self` as this ensures `T` is used in constants of the form `<Self as Foo<T>>`.
Due to an oversight on my part, when landing #75260 and #75255, some tests started failing when polymorphization was enabled that I didn't notice until after landing - this PR fixes the regressions from #75260.
r? @lcnr
Use existing `infcx` when emitting trait impl diagnostic
Fixes#75361Fixes#74918
Previously, we were creating a new `InferCtxt`, which caused an ICE when
used with type variables from the existing `InferCtxt`
Clean up errors in typeck and resolve
* Tweak ordering of suggestions
* Do not suggest similarly named enclosing item
* Point at item definition in foreign crates
* Add missing primary label
CC #34255.