a general type system cleanup
removes the helper functions `traits::fully_solve_X` as they add more complexity then they are worth. It's confusing which of these helpers should be used in which context.
changes the way we deal with overflow to always add depth in `evaluate_predicates_recursively`. It may make sense to actually fully transition to not have `recursion_depth` on obligations but that's probably a bit too much for this PR.
also removes some other small - and imo unnecessary - helpers.
r? types
Remove box expressions from HIR
After #108516, `#[rustc_box]` is used at HIR->THIR lowering and this is no longer emitted, so it can be removed.
This is based on top of #108471 to help with conflicts, so 43490488ccacd1a822e9c621f5ed6fca99959a0b is the only relevant commit (sorry for all the duplicated pings!)
````@rustbot```` label +S-blocked
Wrap the whole LocalInfo in ClearCrossCrate.
MIR contains a lot of information about locals. The primary purpose of this information is the quality of borrowck diagnostics.
This PR aims to drop this information after MIR analyses are finished, ie. starting from post-cleanup runtime MIR.
Implement checked Shl/Shr at MIR building.
This does not require any special handling by codegen backends,
as the overflow behaviour is entirely determined by the rhs (shift amount).
This allows MIR ConstProp to remove the overflow check for constant shifts.
~There is an existing different behaviour between cg_llvm and cg_clif (cc `@bjorn3).`
I took cg_llvm's one as reference: overflow if `rhs < 0 || rhs > number_of_bits_in_lhs_ty`.~
EDIT: `cg_llvm` and `cg_clif` implement the overflow check differently. This PR uses `cg_llvm`'s implementation based on a `BitAnd` instead of `cg_clif`'s one based on an unsigned comparison.
Ensure value is on the on-disk cache before returning from `ensure()`.
The current logic for `ensure()` a query just checks that the node is green in the dependency graph.
However, a lot of places use `ensure()` to prevent the query from being called later. This is the case before stealing a query result.
If the query is actually green but the value is not available in the on-disk cache, `ensure` would return, but a subsequent call to the full query would run the code, and attempt to read from a stolen value.
This PR conforms the query system to the usage by checking whether the queried value is loadable from disk before returning.
Sadly, I can't manage to craft a proper test...
Should fix all instances of "attempted to read from stolen value".
tidy: enforce comment blocks to have an even number of backticks
After PR #108694, most unmatched backticks in `compiler/` comments have been eliminated. This PR adds a tidy lint to ensure no new unmatched backticks are added, and either addresses the lint in the remaining instances it found, or allows it.
Very often, backtick containing sections wrap around lines, for example:
```Rust
// This function takes a tuple `(Vec<String>,
// Box<[u8]>)` and transforms it into `Vec<u8>`.
```
The lint is implemented to work on top of blocks, counting each line with a `//` into a block, and counting if there are an odd or even number of backticks in the entire block, instead of looking at just a single line.
This makes it easier to open the messages file while developing on features.
The commit was the result of automatted changes:
for p in compiler/rustc_*; do mv $p/locales/en-US.ftl $p/messages.ftl; rmdir $p/locales; done
for p in compiler/rustc_*; do sed -i "s#\.\./locales/en-US.ftl#../messages.ftl#" $p/src/lib.rs; done
rustc_middle: Remove trait `DefIdTree`
This trait was a way to generalize over both `TyCtxt` and `Resolver`, but now `Resolver` has access to `TyCtxt`, so this trait is no longer necessary.
Desugaring of drop and replace at MIR build
This commit desugars the drop and replace deriving from an
assignment at MIR build, avoiding the construction of the
`DropAndReplace` terminator (which will be removed in a following PR).
In order to retain the same error messages for replaces a new
`DesugaringKind::Replace` variant is introduced.
The changes in the borrowck are also useful for future work in moving drop elaboration
before borrowck, as no `DropAndReplace` would be present there anymore.
Notes on test diffs:
* `tests/ui/borrowck/issue-58776-borrowck-scans-children`: the assignment deriving from the desugaring kills the borrow.
* `tests/ui/async-await/async-fn-size-uninit-locals.rs`, `tests/mir-opt/issue_41110.test.ElaborateDrops.after.mir`, `tests/mir-opt/issue_41888.main.ElaborateDrops.after.mir`: drop elaboration generates (or reads from) a useless drop flag due to an issue with the dataflow analysis. Will be fixed independently by https://github.com/rust-lang/rust/pull/106430.
See https://github.com/rust-lang/rust/pull/104488 for more context
Don't call `temporary_scope` twice.
`mirror_expr_inner` calls `temporary_scope`. It then calls `make_mirror_unadjusted` which makes an identical call to `temporary_scope`.
This commit changes the `mirror_expr_inner` to get the `temp_lifetime` out of the expression produced by `make_mirror_unadjusted`, similar to how it currently gets the type.
r? `@cjgillot`
This commit desugars the drop and replace deriving from an
assignment at MIR build, avoiding the construction of the
DropAndReplace terminator (which will be removed in a followign PR)
In order to retain the same error messages for replaces a new
DesugaringKind::Replace variant is introduced.
`mirror_expr_inner` calls `temporary_scope`. It then calls
`make_mirror_unadjusted` which makes an identical call to
`temporary_scope`.
This commit changes the `mirror_expr_inner` to get the `temp_lifetime`
out of the expression produced by `make_mirror_unadjusted`, similar to
how it currently gets the type.
Restrict `#[rustc_box]` to `Box::new` calls
Currently, `#[rustc_box]` can be applied to any call expression with a single argument. This PR only allows it to be applied to calls to `Box::new`
Avoid invoking typeck from borrowck
This PR attempts to reduce direct dependencies between typeck and MIR-related queries. The goal is to have all the information transit either through THIR or through dedicated queries that avoid depending on the whole `TypeckResults`.
In a first commit, we store the type information that MIR building requires into THIR. This avoids edges between mir_built and typeck.
In the second and third commit, we wrap informations around closures (upvars, kind origin and user-provided signature) to avoid borrowck depending on typeck information.
There should be a single remaining borrowck -> typeck edge in the good path, due to inline consts.
Move THIR printing to rustc_mir_build.
https://github.com/rust-lang/rust/pull/107451 increased the compilation time of `rustc_middle` by 10% = 3s.
As https://github.com/rust-lang/rust/pull/107006 adds quite a lot of code to rustc_middle, I suspect it to be the cause.
This PR moves the THIR printing code to `rustc_mir_build`, where the query provider lives, in order to benefit from higher parallelism when compiling rustc.
(This is a large commit. The changes to
`compiler/rustc_middle/src/ty/context.rs` are the most important ones.)
The current naming scheme is a mess, with a mix of `_intern_`, `intern_`
and `mk_` prefixes, with little consistency. In particular, in many
cases it's easy to use an iterator interner when a (preferable) slice
interner is available.
The guiding principles of the new naming system:
- No `_intern_` prefixes.
- The `intern_` prefix is for internal operations.
- The `mk_` prefix is for external operations.
- For cases where there is a slice interner and an iterator interner,
the former is `mk_foo` and the latter is `mk_foo_from_iter`.
Also, `slice_interners!` and `direct_interners!` can now be `pub` or
non-`pub`, which helps enforce the internal/external operations
division.
It's not perfect, but I think it's a clear improvement.
The following lists show everything that was renamed.
slice_interners
- const_list
- mk_const_list -> mk_const_list_from_iter
- intern_const_list -> mk_const_list
- substs
- mk_substs -> mk_substs_from_iter
- intern_substs -> mk_substs
- check_substs -> check_and_mk_substs (this is a weird one)
- canonical_var_infos
- intern_canonical_var_infos -> mk_canonical_var_infos
- poly_existential_predicates
- mk_poly_existential_predicates -> mk_poly_existential_predicates_from_iter
- intern_poly_existential_predicates -> mk_poly_existential_predicates
- _intern_poly_existential_predicates -> intern_poly_existential_predicates
- predicates
- mk_predicates -> mk_predicates_from_iter
- intern_predicates -> mk_predicates
- _intern_predicates -> intern_predicates
- projs
- intern_projs -> mk_projs
- place_elems
- mk_place_elems -> mk_place_elems_from_iter
- intern_place_elems -> mk_place_elems
- bound_variable_kinds
- mk_bound_variable_kinds -> mk_bound_variable_kinds_from_iter
- intern_bound_variable_kinds -> mk_bound_variable_kinds
direct_interners
- region
- intern_region (unchanged)
- const
- mk_const_internal -> intern_const
- const_allocation
- intern_const_alloc -> mk_const_alloc
- layout
- intern_layout -> mk_layout
- adt_def
- intern_adt_def -> mk_adt_def_from_data (unusual case, hard to avoid)
- alloc_adt_def(!) -> mk_adt_def
- external_constraints
- intern_external_constraints -> mk_external_constraints
Other
- type_list
- mk_type_list -> mk_type_list_from_iter
- intern_type_list -> mk_type_list
- tup
- mk_tup -> mk_tup_from_iter
- intern_tup -> mk_tup
Use `tcx.ty_error_with_guaranteed` in more places, rename variants
1. Use `ty_error_with_guaranteed` more so we don't delay so many span bugs
2. Rename `ty_error_with_guaranteed` to `ty_error`, `ty_error` to `ty_error_misc`. This is to incentivize using the former over the latter in cases where we already are witness to a `ErrorGuaranteed` token.
Second commit is just name replacement, so the first commit can be reviewed on its own with more scrutiny.
Use associated type bounds in some places in the compiler
Use associated type bounds for some nested `impl Trait<Assoc = impl Trait2>` cases. I'm generally keen to introduce new lang features that are more mature into the compiler, but maybe let's see what others think?
Side-note: I was surprised that the only use-cases of nested impl trait in the compiler are just iterator related?!
Remove type-traversal trait aliases
#107924 moved the type traversal (folding and visiting) traits into the type library, but created trait aliases in `rustc_middle` to minimise both the API churn for trait consumers and the arising boilerplate. As mentioned in that PR, an alternative approach of defining subtraits with blanket implementations of the respective supertraits was also considered at that time but was ruled out as not adding much value.
Unfortunately, it has since emerged that rust-analyzer has difficulty with these trait aliases at present, resulting in a degraded contributor experience (see the recent [r-a has become useless](https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/r-a.20has.20become.20useless) topic on the #t-compiler/help Zulip stream).
This PR removes the trait aliases, and accordingly the underlying type library traits are now used directly; they are parameterised by `TyCtxt<'tcx>` rather than just the `'tcx` lifetime, and imports have been updated to reflect the fact that the trait aliases' explicitly named traits are no longer automatically brought into scope. These changes also roll-back the (no-longer required) workarounds to #107747 that were made in b409329c62.
Since this PR is just a find+replace together with the changes necessary for compilation & tidy to pass, it's currently just one mega-commit. Let me know if you'd like it broken up.
r? `@oli-obk`
Instead of loading the Fluent resources for every crate in
`rustc_error_messages`, each crate generates typed identifiers for its
own diagnostics and creates a static which are pulled together in the
`rustc_driver` crate and provided to the diagnostic emitter.
Signed-off-by: David Wood <david.wood@huawei.com>
Rollup of 7 pull requests
Successful merges:
- #106347 (More accurate spans for arg removal suggestion)
- #108057 (Prevent some attributes from being merged with others on reexports)
- #108090 (`if $c:expr { Some($r:expr) } else { None }` =>> `$c.then(|| $r)`)
- #108092 (note issue for feature(packed_bundled_libs))
- #108099 (use chars instead of strings where applicable)
- #108115 (Do not ICE on unmet trait alias bounds)
- #108125 (Add new people to the compiletest review rotation)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Much like there are specialized variants of `mk_ty`. This will enable
some optimization in the next commit.
Also rename the existing `re_error*` functions as `mk_re_error*`, for
consistency.
Output tree representation on thir-tree
The current output of `-Zunpretty=thir-tree` is really cumbersome to work with, using an actual tree representation should make it easier to see what the thir looks like.
Rollup of 8 pull requests
Successful merges:
- #106904 (Preserve split DWARF files when building archives.)
- #106971 (Handle diagnostics customization on the fluent side (for one specific diagnostic))
- #106978 (Migrate mir_build's borrow conflicts)
- #107150 (`ty::tls` cleanups)
- #107168 (Use a type-alias-impl-trait in `ObligationForest`)
- #107189 (Encode info for Adt in a single place.)
- #107322 (Custom mir: Add support for some remaining, easy to support constructs)
- #107323 (Disable ConstGoto opt in cleanup blocks)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Custom mir: Add support for some remaining, easy to support constructs
Some documentation for previous changes and support for `Deinit`, checked binops, len, and array repetition
r? ```@oli-obk``` or ```@tmiasko```
Migrate mir_build's borrow conflicts
This also changes the error message slightly, for two reasons:
- I'm not a fan of saying "value borrowed, by `x`, here"
- it simplifies the error implementation significantly.
Move format_args!() into AST (and expand it during AST lowering)
Implements https://github.com/rust-lang/compiler-team/issues/541
This moves FormatArgs from rustc_builtin_macros to rustc_ast_lowering. For now, the end result is the same. But this allows for future changes to do smarter things with format_args!(). It also allows Clippy to directly access the ast::FormatArgs, making things a lot easier.
This change turns the format args types into lang items. The builtin macro used to refer to them by their path. After this change, the path is no longer relevant, making it easier to make changes in `core`.
This updates clippy to use the new language items, but this doesn't yet make clippy use the ast::FormatArgs structure that's now available. That should be done after this is merged.
Custom MIR: Support binary and unary operations
Lower binary and unary operations directly to corresponding unchecked MIR
operations. Ultimately this might not be syntax we want, but it allows for
experimentation in the meantime.
r? ````@oli-obk```` ````@JakobDegen````
use LocalDefId instead of HirId in trait resolution to simplify
the obligation clause resolution
Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
Rollup of 8 pull requests
Successful merges:
- #106783 (Recover labels written as identifiers)
- #106973 (Don't treat closures from other crates as local)
- #106979 (Document how to get the type of a default associated type)
- #107053 (signal update string representation for haiku.)
- #107058 (Recognise double-equals homoglyph)
- #107067 (Custom MIR: Support storage statements)
- #107076 (Added const-generic ui test case for issue #106419)
- #107091 (Fix broken format strings in `infer.ftl`)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Switching them to `Break(())` and `Continue(())` instead.
libs-api would like to remove these constants, so stop using them in compiler to make the removal PR later smaller.
Migrate mir_build diagnostics 2 of 3
The first three commits are fairly boring, however I've made some changes to the output of the match checking diagnostics.
Rename `hir::Map::{get_,find_}parent_node` to `hir::Map::{,opt_}parent_id`, and add `hir::Map::{get,find}_parent`
The `hir::Map::get_parent_node` function doesn't return a `Node`, and I think that's quite confusing. Let's rename it to something that sounds more like something that gets the parent hir id => `hir::Map::parent_id`. Same with `find_parent_node` => `opt_parent_id`.
Also, combine `hir.get(hir.parent_id(hir_id))` and similar `hir.find(hir.parent_id(hir_id))` function into new functions that actually retrieve the parent node in one call. This last commit is the only one that might need to be looked at closely.
Clarify that raw retags are not permitted in Mir
Not sure when this changed, but documentation and the validator needed to be updated. This also removes raw retags from custom mir.
cc rust-lang/miri#2735
r? `@RalfJung`
Improve syntax of `newtype_index`
This makes it more like proper Rust and also makes the implementation a lot simpler.
Mostly just turns weird flags in the body into proper attributes.
It should probably also be converted to an attribute macro instead of function-like, but that can be done in a future PR.
Remove the `..` from the body, only a few invocations used it and it's
inconsistent with rust syntax.
Use `;` instead of `,` between consts. As the Rust syntax gods inteded.
Migrate rustc_mir_build diagnostics
Rebases https://github.com/rust-lang/rust/pull/100854
~~The remaining issue is how to better resolve 72bea68af4~~
~~The diagnostic macros seems to generate a broken diagnostic, and I couldn't figure out how to manually format the fluent message, so I hardcoded the format string for now. I'd like pointers to a better fix for this.~~
Also, I'm not 100% sure I didn't mess up a rebase somewhere 🙂
r? `@davidtwco`
Support call and drop terminators in custom mir
The only caveat with this change is that cleanup blocks are not supported. I would like to add them, but it's not quite clear to me what the best way to do that is, so I'll have to think about it some more.
r? ``@oli-obk``
Custom MIR: Many more improvements
Commits are each atomic changes, best reviewed one at a time, with the exception that the last commit includes all the documentation.
### First commit
Unsafetyck was not correctly disabled before for `dialect = "built"` custom MIR. This is fixed and a regression test is added.
### Second commit
Implements `Discriminant`, `SetDiscriminant`, and `SwitchInt`.
### Third commit
Implements indexing, field, and variant projections.
### Fourth commit
Documents the previous commits and everything else.
There is some amount of weirdness here due to having to beat Rust syntax into cooperating with MIR concepts, but it hopefully should not be too much. All of it is documented.
r? `@oli-obk`
Combine `ty::Projection` and `ty::Opaque` into `ty::Alias`
Implements https://github.com/rust-lang/types-team/issues/79.
This PR consolidates `ty::Projection` and `ty::Opaque` into a single `ty::Alias`, with an `AliasKind` and `AliasTy` type (renamed from `ty::ProjectionTy`, which is the inner data of `ty::Projection`) defined as so:
```
enum AliasKind {
Projection,
Opaque,
}
struct AliasTy<'tcx> {
def_id: DefId,
substs: SubstsRef<'tcx>,
}
```
Since we don't have access to `TyCtxt` in type flags computation, and because repeatedly calling `DefKind` on the def-id is expensive, these two types are distinguished with `ty::AliasKind`, conveniently glob-imported into `ty::{Projection, Opaque}`. For example:
```diff
match ty.kind() {
- ty::Opaque(..) =>
+ ty::Alias(ty::Opaque, ..) => {}
_ => {}
}
```
This PR also consolidates match arms that treated `ty::Opaque` and `ty::Projection` identically.
r? `@ghost`
Change pattern borrowing suggestions to be verbose and remove invalid suggestion
Synthesize a more accurate span and use verbose suggestion output to
make the message clearer.
Do not suggest borrowing binding in pattern in let else. Fix#104838.
Allow unsafe through inline const
Handle similar to closures.
Address https://github.com/rust-lang/rust/pull/104087#issuecomment-1324173328
Note that this PR does not fix the issue for `unsafe { [0; function_requiring_unsafe()] }`. This is fundamentally unfixable for MIR unsafeck IMO.
This PR also does not fix unsafety checking for inline const in pattern position. It actually breaks it, allowing unsafe functions to be used in inline const in pattern position without unsafe blocks. Inline const in pattern position is not visible in MIR so ignored by MIR unsafety checking (currently it is also not checked by borrow checker, which is the reason why it's considered an incomplete feature).
`@rustbot` label: +T-lang +F-inline_const
Remove `token::Lit` from `ast::MetaItemLit`.
Currently `ast::MetaItemLit` represents the literal kind twice. This PR removes that redundancy. Best reviewed one commit at a time.
r? `@petrochenkov`
compiler: remove unnecessary imports and qualified paths
Some of these imports were necessary before Edition 2021, others were already in the prelude.
I hope it's fine that this PR is so spread-out across files :/
This is required to distinguish between cooked and raw byte string
literals in an `ast::LitKind`, without referring to an adjacent
`token::Lit`. It's a prerequisite for the next commit.
`mk_const(ty::ConstKind::X(...), ty)` can now be simplified to
`mk_cosnt(..., ty)`.
I searched with the following regex: \mk_const\([\n\s]*(ty::)?ConstKind\
I've left `ty::ConstKind::{Bound, Error}` as-is, they seem clearer this
way.
Use `as_deref` in compiler (but only where it makes sense)
This simplifies some code :3
(there are some changes that are not exacly `as_deref`, but more like "clever `Option`/`Result` method use")
Only declare bindings for if-let guards once per arm
Currently, each candidate for a match arm uses separate locals for the bindings in the if-let guard, causing problems (#88015) when those branches converge in the arm body.
Fixes#88015 (🤞)