Continue work on associated const equality
This actually implements some more complex logic for assigning associated consts to values.
Inside of projection candidates, it now defers to a separate function for either consts or
types. To reduce amount of code, projections are now generic over T, where T is either a Type or
a Const. I can add some comments back later, but this was the fastest way to implement it.
It also now finds the correct type of consts in type_of.
---
The current main TODO is finding the const of the def id for the LeafDef.
Right now it works if the function isn't called, but once you use the trait impl with the bound it fails inside projection.
I was hoping to get some help in getting the `&'tcx ty::Const<'tcx>`, in addition to a bunch of other `todo!()`s which I think may not be hit.
r? `@oli-obk`
Updates #92827
If hir_owner is Owner(_), the LocalDefId is pointing to an owner, so the ItemLocalId is 0.
If the HIR node does not exist, we store Phantom.
Otherwise, we store the HirId associated to the LocalDefId.
Print a helpful message if unwinding aborts when it reaches a nounwind function
This is implemented by routing `TerminatorKind::Abort` back through the panic handler, but with a special flag in the `PanicInfo` which indicates that the panic handler should *not* attempt to unwind the stack and should instead abort immediately.
This is useful for the planned change in https://github.com/rust-lang/lang-team/issues/97 which would make `Drop` impls `nounwind` by default.
### Code
```rust
#![feature(c_unwind)]
fn panic() {
panic!()
}
extern "C" fn nounwind() {
panic();
}
fn main() {
nounwind();
}
```
### Before
```
$ ./test
thread 'main' panicked at 'explicit panic', test.rs:4:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Illegal instruction (core dumped)
```
### After
```
$ ./test
thread 'main' panicked at 'explicit panic', test.rs:4:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'main' panicked at 'panic in a function that cannot unwind', test.rs:7:1
stack backtrace:
0: 0x556f8f86ec9b - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hdccefe11a6ac4396
1: 0x556f8f88ac6c - core::fmt::write::he152b28c41466ebb
2: 0x556f8f85d6e2 - std::io::Write::write_fmt::h0c261480ab86f3d3
3: 0x556f8f8654fa - std::panicking::default_hook::{{closure}}::h5d7346f3ff7f6c1b
4: 0x556f8f86512b - std::panicking::default_hook::hd85803a1376cac7f
5: 0x556f8f865a91 - std::panicking::rust_panic_with_hook::h4dc1c5a3036257ac
6: 0x556f8f86f079 - std::panicking::begin_panic_handler::{{closure}}::hdda1d83c7a9d34d2
7: 0x556f8f86edc4 - std::sys_common::backtrace::__rust_end_short_backtrace::h5b70ed0cce71e95f
8: 0x556f8f865592 - rust_begin_unwind
9: 0x556f8f85a764 - core::panicking::panic_no_unwind::h2606ab3d78c87899
10: 0x556f8f85b910 - test::nounwind::hade6c7ee65050347
11: 0x556f8f85b936 - test::main::hdc6e02cb36343525
12: 0x556f8f85b7e3 - core::ops::function::FnOnce::call_once::h4d02663acfc7597f
13: 0x556f8f85b739 - std::sys_common::backtrace::__rust_begin_short_backtrace::h071d40135adb0101
14: 0x556f8f85c149 - std::rt::lang_start::{{closure}}::h70dbfbf38b685e93
15: 0x556f8f85c791 - std::rt::lang_start_internal::h798f1c0268d525aa
16: 0x556f8f85c131 - std::rt::lang_start::h476a7ee0a0bb663f
17: 0x556f8f85b963 - main
18: 0x7f64c0822b25 - __libc_start_main
19: 0x556f8f85ae8e - _start
20: 0x0 - <unknown>
thread panicked while panicking. aborting.
Aborted (core dumped)
```
Rollup of 17 pull requests
Successful merges:
- #91032 (Introduce drop range tracking to generator interior analysis)
- #92856 (Exclude "test" from doc_auto_cfg)
- #92860 (Fix errors on blanket impls by ignoring the children of generated impls)
- #93038 (Fix star handling in block doc comments)
- #93061 (Only suggest adding `!` to expressions that can be macro invocation)
- #93067 (rustdoc mobile: fix scroll offset when jumping to internal id)
- #93086 (Add tests to ensure that `let_chains` works with `if_let_guard`)
- #93087 (Fix src/test/run-make/raw-dylib-alt-calling-convention)
- #93091 (⬆ chalk to 0.76.0)
- #93094 (src/test/rustdoc-json: Check for `struct_field`s in `variant_tuple_struct.rs`)
- #93098 (Show a more informative panic message when `DefPathHash` does not exist)
- #93099 (rustdoc: auto create output directory when "--output-format json")
- #93102 (Pretty printer algorithm revamp step 3)
- #93104 (Support --bless for pp-exact pretty printer tests)
- #93114 (update comment for `ensure_monomorphic_enough`)
- #93128 (Add script to prevent point releases with same number as existing ones)
- #93136 (Backport the 1.58.1 release notes to master)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
ProjectionPredicate should be able to handle both associated types and consts so this adds the
first step of that. It mainly just pipes types all the way down, not entirely sure how to handle
consts, but hopefully that'll come with time.
Replace `NestedVisitorMap` with generic `NestedFilter`
This is an attempt to make the `intravisit::Visitor` API simpler and "more const" with regard to nested visiting.
With this change, `intravisit::Visitor` does not visit nested things by default, unless you specify `type NestedFilter = nested_filter::OnlyBodies` (or `All`). `nested_visit_map` returns `Self::Map` instead of `NestedVisitorMap<Self::Map>`. It panics by default (unreachable if `type NestedFilter` is omitted).
One somewhat trixty thing here is that `nested_filter::{OnlyBodies, All}` live in `rustc_middle` so that they may have `type Map = map::Map` and so that `impl Visitor`s never need to specify `type Map` - it has a default of `Self::NestedFilter::Map`.
Remove deprecated LLVM-style inline assembly
The `llvm_asm!` was deprecated back in #87590 1.56.0, with intention to remove
it once `asm!` was stabilized, which already happened in #91728 1.59.0. Now it
is time to remove `llvm_asm!` to avoid continued maintenance cost.
Closes#70173.
Closes#92794.
Closes#87612.
Closes#82065.
cc `@rust-lang/wg-inline-asm`
r? `@Amanieu`
Link impl items to corresponding trait items in late resolver.
Hygienically linking trait impl items to declarations in the trait can be done directly by the late resolver. In fact, it is already done to diagnose unknown items.
This PR uses this resolution work and stores the `DefId` of the trait item in the HIR. This avoids having to do this resolution manually later.
r? `@matthewjasper`
Related to #90639. The added `trait_item_id` field can be moved to `ImplItemRef` to be used directly by your PR.
Hash `Ident` spans in all HIR structures
This PR removes all of the `#[stable_hasher(project(name))]`
attributes used in HIR structs. While these attributes are not known
to be causing any issues in practice, we need to hash these in
order for the incremental system to work correctly -
a query could be otherwise be incorrectly marked green
when a change occures in one of the `Span`s that it uses.
This PR removes all of the `#[stable_hasher(project(name))]`
attributes used in HIR structs. While these attributes are not known
to be causing any issues in practice, we need to hash these in
order for the incremental system to work correctly -
a query could be otherwise be incorrectly marked green
when a change occures in one of the `Span`s that it uses.
All other 'containers' (e.g. `impl` blocks) hashed their contents
in the normal, order-dependent way. However, `Mod` was hashing
its contents in a (sort-of) order-independent way. However, the
exact order is exposed to consumers through `Mod.item_ids`,
and through query results like `hir_module_items`. Therefore,
stable hashing needs to take the order of items into account,
to avoid fingerprint ICEs.
Unforuntately, I was unable to directly build a reproducer
for the ICE, due to the behavior of `Fingerprint::combine_commutative`.
This operation swaps the upper and lower `u64` when constructing the
result, which makes the function non-associative. Since we start
the hashing of module items by combining `Fingerprint::ZERO` with
the first item, it's difficult to actually build an example where
changing the order of module items leaves the final hash unchanged.
However, this appears to have been hit in practice in #92218
While we're not able to reproduce it, the fact that proc-macros
are involved (which can give an entire module the same span, preventing
any span-related invalidations) makes me confident that the root
cause of that issue is our method of hashing module items.
This PR removes all of the special handling for `Mod`, instead deriving
a `HashStable` implementation. This makes `Mod` consistent with other
'contains' like `Impl`, which hash their contents through the typical
derive of `HashStable`.
Remove `SymbolStr`
This was originally proposed in https://github.com/rust-lang/rust/pull/74554#discussion_r466203544. As well as removing the icky `SymbolStr` type, it allows the removal of a lot of `&` and `*` occurrences.
Best reviewed one commit at a time.
r? `@oli-obk`
Implement let-else type annotations natively
Tracking issue: #87335Fixes#89688, fixes#89807, edit: fixes #89960 as well
As explained in https://github.com/rust-lang/rust/issues/89688#issuecomment-940405082, the previous desugaring moved the let-else scrutinee into a dummy variable, which meant if you wanted to refer to it again in the else block, it had moved.
This introduces a new hir type, ~~`hir::LetExpr`~~ `hir::Let`, which takes over all the fields of `hir::ExprKind::Let(...)` and adds an optional type annotation. The `hir::Let` is then treated like a `hir::Local` when type checking a function body, specifically:
* `GatherLocalsVisitor` overrides a new `Visitor::visit_let_expr` and does pretty much exactly what it does for `visit_local`, assigning a local type to the `hir::Let` ~~(they could be deduplicated but they are right next to each other, so at least we know they're the same)~~
* It reuses the code in `check_decl_local` to typecheck the `hir::Let`, simply returning 'bool' for the expression type after doing that.
* ~~`FnCtxt::check_expr_let` passes this local type in to `demand_scrutinee_type`, and then imitates check_decl_local's pattern checking~~
* ~~`demand_scrutinee_type` (the blindest change for me, please give this extra scrutiny) uses this local type instead of of creating a new one~~
* ~~Just realised the `check_expr_with_needs` was passing NoExpectation further down, need to pass the type there too. And apparently this Expectation API already exists.~~
Some other misc notes:
* ~~Is the clippy code supposed to be autoformatted? I tried not to give huge diffs but maybe some rustfmt changes simply haven't hit it yet.~~
* in `rustc_ast_lowering/src/block.rs`, I noticed some existing `self.alias_attrs()` calls in `LoweringContext::lower_stmts` seem to be copying attributes from the lowered locals/etc to the statements. Is that right? I'm new at this, I don't know.
Handle unordered const/ty generics for object lifetime defaults
*feel like I should have a PR description but cant think of what to put here*
r? ```@lcnr```
Tweak errors coming from `for`-loop, `?` and `.await` desugaring
* Suggest removal of `.await` on non-`Future` expression
* Keep track of obligations introduced by desugaring
* Remove span pointing at method for obligation errors coming from desugaring
* Point at called local sync `fn` and suggest making it `async`
```
error[E0277]: `()` is not a future
--> $DIR/unnecessary-await.rs:9:10
|
LL | boo().await;
| -----^^^^^^ `()` is not a future
| |
| this call returns `()`
|
= help: the trait `Future` is not implemented for `()`
help: do not `.await` the expression
|
LL - boo().await;
LL + boo();
|
help: alternatively, consider making `fn boo` asynchronous
|
LL | async fn boo () {}
| +++++
```
Fix#66731.
Stabilize asm! and global_asm!
Tracking issue: #72016
It's been almost 2 years since the original [RFC](https://github.com/rust-lang/rfcs/pull/2850) was posted and we're finally ready to stabilize this feature!
The main changes in this PR are:
- Removing `asm!` and `global_asm!` from the prelude as per the decision in #87228.
- Stabilizing the `asm` and `global_asm` features.
- Removing the unstable book pages for `asm` and `global_asm`. The contents are moved to the [reference](https://github.com/rust-lang/reference/pull/1105) and [rust by example](https://github.com/rust-lang/rust-by-example/pull/1483).
- All links to these pages have been removed to satisfy the link checker. In a later PR these will be replaced with links to the reference or rust by example.
- Removing the automatic suggestion for using `llvm_asm!` instead of `asm!` if you're still using the old syntax, since it doesn't work anymore with `asm!` no longer being in the prelude. This only affects code that predates the old LLVM-style `asm!` being renamed to `llvm_asm!`.
- Updating `stdarch` and `compiler-builtins`.
- Updating all the tests.
r? `@joshtriplett`
Stabilise `feature(const_generics_defaults)`
`feature(const_generics_defaults)` is complete implementation wise and has a pretty extensive test suite so I think is ready for stabilisation.
needs stabilisation report and maybe an RFC 😅
r? `@lcnr`
cc `@rust-lang/project-const-generics`
Keep spans for generics in `#[derive(_)]` desugaring
Keep the spans for generics coming from a `derive`d Item, so that errors
and suggestions have better detail.
Fix#84003.
Reintroduce `into_future` in `.await` desugaring
This is a reintroduction of the remaining parts from https://github.com/rust-lang/rust/pull/65244 that have not been relanded yet.
This isn't quite ready to merge yet. The last attempt was reverting due to performance regressions, so we need to make sure this does not introduce those issues again.
Issues #67644, #67982
/cc `@yoshuawuyts`
* Annotate `derive`d spans from the user's code with the appropciate context
* Add `Span::can_be_used_for_suggestion` to query if the underlying span
at the users' code
Cleanup: Eliminate ConstnessAnd
This is almost a behaviour-free change and purely a refactoring. "almost" because we appear to be using the wrong ParamEnv somewhere already, and this is now exposed by failing a test using the unstable `~const` feature.
We most definitely need to review all `without_const` and at some point should probably get rid of many of them by using `TraitPredicate` instead of `TraitRef`.
This is a continuation of https://github.com/rust-lang/rust/pull/90274.
r? `@oli-obk`
cc `@spastorino` `@ecstatic-morse`
Nothing else makes sense, and there is no "danger" in doing so, as it only does something if there are const bounds, which are unstable. This used to happen implicitly via the inferctxt before, which was much more fragile.
This function parameter attribute was introduced in https://github.com/rust-lang/rust/pull/44866 as an intermediate step in implementing `impl Trait`, it's not necessary or used anywhere by itself.
Because it's always `'tcx`. In fact, some of them use a mixture of
passed-in `$tcx` and hard-coded `'tcx`, so no other lifetime would even
work.
This makes the code easier to read.
Remove `DropArena`.
Most arena-allocate types that impl `Drop` get their own `TypedArena`, but a
few infrequently used ones share a `DropArena`. This sharing adds complexity
but doesn't help performance or memory usage. Perhaps it was more effective in
the past prior to some other improvements to arenas.
This commit removes `DropArena` and the sharing of arenas via the `few`
attribute of the `arena_types` macro. This change removes over 100 lines of
code and nine uses of `unsafe` (one of which affects the parallel compiler) and
makes the remaining code easier to read.
Most arena-allocate types that impl `Drop` get their own `TypedArena`, but a
few infrequently used ones share a `DropArena`. This sharing adds complexity
but doesn't help performance or memory usage. Perhaps it was more effective in
the past prior to some other improvements to arenas.
This commit removes `DropArena` and the sharing of arenas via the `few`
attribute of the `arena_types` macro. This change removes over 100 lines of
code and nine uses of `unsafe` (one of which affects the parallel compiler) and
makes the remaining code easier to read.
Collect `panic/panic_bounds_check` during monomorphization
This would prevent link time errors if these functions are `#[inline]` (e.g. when `panic_immediate_abort` is used).
Fix#90405Fixrust-lang/cargo#10019
`@rustbot` label: T-compiler A-codegen
Remove hir::map::blocks and use FnKind instead
The principal tool is `FnLikeNode`, which is not often used and can be easily implemented using `rustc_hir::intravisit::FnKind`.
Index and hash HIR as part of lowering
Part of https://github.com/rust-lang/rust/pull/88186
~Based on https://github.com/rust-lang/rust/pull/88880 (see merge commit).~
Once HIR is lowered, it is later indexed by the `index_hir` query and hashed for `crate_hash`. This PR moves those post-processing steps to lowering itself. As a side objective, the HIR crate data structure is refactored as an `IndexVec<LocalDefId, Option<OwnerInfo<'hir>>>` where `OwnerInfo` stores all the relevant information for an HIR owner.
r? `@michaelwoerister`
cc `@petrochenkov`
Add `const_eval_select` intrinsic
Adds an intrinsic that calls a given function when evaluated at compiler time, but generates a call to another function when called at runtime.
See https://github.com/rust-lang/const-eval/issues/7 for previous discussion.
r? `@oli-obk.`
Rework HIR API to make invocations of the hir_crate query harder.
`hir_crate` forces the recomputation of queries that depend on it.
This PR aims at avoiding useless invocations of `hir_crate` by making dependent code go through `tcx.hir()`.
Fix ICE when `start` lang item has wrong generics
In my previous pr #87875 I missed the requirements on the `start` lang item due to its relative difficulty to test and opting for more conservative estimates. This fixes that by updating the requirement to be exactly one generic type.
The `start` lang item should have exactly one generic type for the return type of the `main` fn ptr passed to it. I believe having zero would previously *sometimes* compile (often with the use of `fn() -> ()` as the fn ptr but it was likely UB to call if the return type of `main` was not `()` as far as I know) however it also sometimes would not for various errors including ICEs and LLVM errors depending on exact situations. Having more than 1 generic has always failed with an ICE because only the one generic type is expected and provided.
Fixes#79559, fixes#73584, fixes#83117 (all duplicates)
Relevant to #9307
r? ````@cjgillot````
As shown in the two test requirements that got updated, if there's other problems,
then those other problems are probably the root cause of the incorrect generics count.
Gather module items after lowering.
This avoids having a non-local analysis inside lowering.
By implementing `hir_module_items` using a visitor, we make sure that iterations and visitors are consistent.
Simplify lazy DefPathHash decoding by using an on-disk hash table.
This PR simplifies the logic around mapping `DefPathHash` values encountered during incremental compilation to valid `DefId`s in the current session. It is able to do so by using an on-disk hash table encoding that allows for looking up values directly, i.e. without deserializing the entire table.
The main simplification comes from not having to keep track of `DefPathHashes` being used during the compilation session.
Allow `panic!("{}", computed_str)` in const fn.
Special-case `panic!("{}", arg)` and translate it to `panic_display(&arg)`. `panic_display` will behave like `panic_any` in cosnt eval and behave like `panic!(format_args!("{}", arg))` in runtime.
This should bring Rust 2015 and 2021 to feature parity in terms of `const_panic`; and hopefully would unblock the stabilisation of #51999.
`@rustbot` modify labels: +T-compiler +T-libs +A-const-eval +A-const-fn
r? `@oli-obk`
Const drop
The changes are pretty primitive at this point. But at least it works. ^-^
Problems with the current change that I can think of now:
- [x] `~const Drop` shouldn't change anything in the non-const world.
- [x] types that do not have drop glues shouldn't fail to satisfy `~const Drop` in const contexts. `struct S { a: u8, b: u16 }` This might not fail for `needs_non_const_drop`, but it will fail in `rustc_trait_selection`.
- [x] The current change accepts types that have `const Drop` impls but have non-const `Drop` glue.
Fixes#88424.
Significant Changes:
- `~const Drop` is no longer treated as a normal trait bound. In non-const contexts, this bound has no effect, but in const contexts, this restricts the input type and all of its transitive fields to either a) have a `const Drop` impl or b) can be trivially dropped (i.e. no drop glue)
- `T: ~const Drop` will not be linted like `T: Drop`.
- Instead of recursing and iterating through the type in `rustc_mir::transform::check_consts`, we use the trait system to special case `~const Drop`. See [`rustc_trait_selection::...::candidate_assembly#assemble_const_drop_candidates`](https://github.com/fee1-dead/rust/blob/const-drop/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs#L817) and others.
Changes not related to `const Drop`ping and/or changes that are insignificant:
- `Node.constness_for_typeck` no longer returns `hir::Constness::Const` for type aliases in traits. This was previously used to hack how we determine default bound constness for items. But because we now use an explicit opt-in, it is no longer needed.
- Removed `is_const_impl_raw` query. We have `impl_constness`, and the only existing use of that query uses `HirId`, which means we can just operate it with hir.
- `ty::Destructor` now has a field `constness`, which represents the constness of the destructor.
r? `@oli-obk`
Avoid invoking the hir_crate query to traverse the HIR
Walking the HIR tree is done using the `hir_crate` query. However, this is unnecessary, since `hir_owner(CRATE_DEF_ID)` provides the same information. Since depending on `hir_crate` forces dependents to always be executed, this leads to unnecessary work.
By splitting HIR and attributes visits, we can avoid an edge to `hir_crate` when trying to visit the HIR tree.
Fix drop handling for `if let` expressions
MIR lowering for `if let` expressions is now more complicated now that
`if let` exists in HIR. This PR adds a scope for the variables bound in
an `if let` expression and then uses an approach similar to how we
handle loops to ensure that we reliably drop the correct variables.
Closes#88307
cc `@flip1995` `@richkadel` `@c410-f3r`
MIR lowering for `if let` expressions is now more complicated now that
`if let` exists in HIR. This PR adds a scope for the variables bound in
an `if let` expression and then uses an approach similar to how we
handle loops to ensure that we reliably drop the correct variables.
Refactor `named_asm_labels` to a HIR lint
As discussed on #88169, the `named_asm_labels` lint could be moved to a HIR lint. That allows future lints or custom plugins or clippy lints to more easily access the `asm!` macro's data and create better error messages with the lints.
Improve detection of generics on lang items
Adds detection for the required generics for all lang items. Many lang items require an exact or minimum amount of generic arguments and if they don't exist, the compiler will ICE. This does not add any additional validation about bounds on generics or any other lang item restrictions.
Fixes one of the ICEs in #87573
cc `@FabianWolff`
During const eval, this replaces calls to core::panicking::panic_fmt and
std::panicking::being_panic_fmt with a call to a new const fn:
core::panicking::const_panic_fmt. That function uses
fmt::Arguments::as_str() to get the str and calls panic_str with that
instead.
panic!() invocations with formatting arguments are still not accepted,
as the creation of such a fmt::Arguments cannot be done in constant
functions right now.
Store all HIR owners in the same container
This replaces the previous storage in a BTreeMap for each of Item/ImplItem/TraitItem/ForeignItem.
This should allow for a more compact storage.
Based on https://github.com/rust-lang/rust/pull/83114
dont provide fwd declared params to cg defaults
Fixes#83938
```rust
#![feature(const_evaluatable_checked, const_generics, const_generics_defaults)]
#![allow(incomplete_features)]
pub struct Bar<const N: usize, const M: usize = { N + 1 }>;
pub fn foo<const N1: usize>() -> Bar<N1> { loop {} }
fn main() {}
```
This PR makes this code no longer ICE, it was ICE'ing previously because when building substs for `Bar<N1>` we would subst the anon ct: `ConstKind::Unevaluated({N + 1}, substs: [N, M])` with substs of `[N1]`. the anon const has forward declared params supplied though so we end up trying to substitute the provided `M` param which causes the ICE.
This PR doesn't handle the predicates of the const so
```rust
trait Foo<const N: usize> { const Assoc: usize; }
pub struct Bar<const N: usize = { <()>::Assoc }> where (): Foo<N>;
```
Resolves to `<() as Foo<N>>::Assoc` which can allow for using fwd declared params indirectly.
```rust
trait Foo<const N: usize> {}
struct Bar<const N: usize = { 2 + 3 }> where (): Foo<N>;
```
This code also ICEs under this PR because instantiating the default's predicates causes an ICE as predicates_of contains predicates with fwd declared params
PR was briefly discussed [in this zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/260443-project-const-generics/topic/evil.20preds.20in.20param.20env.20.2386580)
Use diagnostic items instead of lang items for rfc2229 migrations
This PR removes the `Send`, `UnwindSafe` and `RefUnwindSafe` lang items introduced in https://github.com/rust-lang/rust/pull/84730, and uses diagnostic items instead to check for `Send`, `UnwindSafe` and `RefUnwindSafe` traits for RFC2229 migrations.
r? ```@nikomatsakis```
Add MIR pass to lower call to `core::slice::len` into `Len` operand
During some larger experiment with range analysis I've found that code like `let l = slice.len()` produces different MIR then one found in bound checks. This optimization pass replaces terminators that are calls to `core::slice::len` with just a MIR operand and Goto terminator.
It uses some heuristics to remove the outer borrow that is made to call `core::slice::len`, but I assume it can be eliminated, just didn't find how.
Would like to express my gratitude to `@oli-obk` who helped me a lot on Zullip
Remove some last remants of {push,pop}_unsafe!
These macros have already been removed, but there was still some code handling these macros. That code is now removed.
Remove unused feature gates
The first commit removes a usage of a feature gate, but I don't expect it to be controversial as the feature gate was only used to workaround a limitation of rust in the past. (closures never being `Clone`)
The second commit uses `#[allow_internal_unstable]` to avoid leaking the `trusted_step` feature gate usage from inside the index newtype macro. It didn't work for the `min_specialization` feature gate though.
The third commit removes (almost) all feature gates from the compiler that weren't used anyway.