Implement partial support for non-lifetime binders
This implements support for non-lifetime binders. It's pretty useless currently, but I wanted to put this up so the implementation can be discussed.
Specifically, this piggybacks off of the late-bound lifetime collection code in `rustc_hir_typeck::collect::lifetimes`. This seems like a necessary step given the fact we don't resolve late-bound regions until this point, and binders are sometimes merged.
Q: I'm not sure if I should go along this route, or try to modify the earlier nameres code to compute the right bound var indices for type and const binders eagerly... If so, I'll need to rename all these queries to something more appropriate (I've done this for `resolve_lifetime::Region` -> `resolve_lifetime::ResolvedArg`)
cc rust-lang/types-team#81
r? `@ghost`
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
Optimize `mk_region`
PR #107869 avoiding some interning under `mk_ty` by special-casing `Ty` variants with simple (integer) bodies. This PR does something similar for regions.
r? `@compiler-errors`
Avoid accessing HIR when it can be avoided
Experiment to see if it helps some incremental cases.
Will be rebased once https://github.com/rust-lang/rust/pull/107942 gets merged.
r? `@ghost`
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.
Implement `deferred_projection_equality` for erica solver
Somewhat of a revival of #96912. When relating projections now emit an `AliasEq` obligation instead of attempting to determine equality of projections that may not be as normalized as possible (i.e. because of lazy norm, or just containing inference variables that prevent us from resolving an impl). Only do this when the new solver is enabled
Modify existing bounds if they exist
Fixes#107335.
This implementation is kinda gross but I don't really see a better way to do it.
This primarily does two things: Modifies `suggest_constraining_type_param` to accept a new parameter that indicates a span to be replaced instead of added, if presented, and limit the additive suggestions to either suggest a new bound on an existing bound (see newly added unit test) or add the generics argument if a generics argument wasn't found.
The former change is required to retain the capability to add an entirely new bounds if it was entirely omitted.
r? ``@compiler-errors``
Track bound types like bound regions
When we instantiate bound types into placeholder types, we throw away the names for some reason. These names are particularly useful for error reporting once we have `for<T>` binders.
r? types
Modify primary span label for E0308
Looking at the reactions to https://hachyderm.io/`@ekuber/109622160673605438,` a lot of people seem to have trouble understanding the current output, where the primary span label on type errors talks about the specific types that diverged, but these can be deeply nested type parameters. Because of that we could see "expected i32, found u32" in the label while the note said "expected Vec<i32>, found Vec<u32>". This understandably confuses people. I believe that once people learn to read these errors it starts to make more sense, but this PR changes the output to be more in line with what people might expect, without sacrificing terseness.
Fix#68220.
Skip possible where_clause_object_safety lints when checking `multiple_supertrait_upcastable`
Fix#106247
To achieve this, I lifted the `WhereClauseReferencesSelf` out from `object_safety_violations` and move it into `is_object_safe` (which is changed to a new query).
cc `@dtolnay`
r? `@compiler-errors`
Remove HirId -> LocalDefId map from HIR.
Having this map in HIR prevents the creating of new definitions after HIR has been built.
Thankfully, we do not need it.
Based on https://github.com/rust-lang/rust/pull/103902
internally change regions to be covariant
Surprisingly, we consider the reference type `&'a T` to be contravaraint in its lifetime parameter. This is confusing and conflicts with the documentation we have in the reference, rustnomicon, and rustc-dev-guide. This also arguably not the correct use of terminology since we can use `&'static u8` in a place where `&' a u8` is expected, this implies that `&'static u8 <: &' a u8` and consequently `'static <: ' a`, hence covariance.
Because of this, when relating two types, we used to switch the argument positions in a confusing way:
`Subtype(&'a u8 <: &'b u8) => Subtype('b <: 'a) => Outlives('a: 'b) => RegionSubRegion('b <= 'a)`
The reason for the current behavior is probably that we wanted `Subtype('b <: 'a)` and `RegionSubRegion('b <= 'a)` to be equivalent, but I don' t think this is a good reason since these relations are sufficiently different in that the first is a relation in the subtyping lattice and is intrinsic to the type-systems, while the the second relation is an implementation detail of regionck.
This PR changes this behavior to use covariance, so..
`Subtype(&'a u8 <: &'b u8) => Subtype('a <: 'b) => Outlives('a: 'b) => RegionSubRegion('b <= 'a) `
Resolves#103676
r? `@lcnr`
use LocalDefId instead of HirId in trait resolution to simplify
the obligation clause resolution
Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
Use UnordMap and UnordSet for id collections (DefIdMap, LocalDefIdMap, etc)
This PR changes the `rustc_data_structures::define_id_collections!` macro to use `UnordMap` and `UnordSet` instead of `FxHashMap` and `FxHashSet`. This should account for a large portion of hash-maps being used in places where they can cause trouble.
The changes required are moderate but non-zero:
- In some places the collections are extracted into sorted vecs.
- There are a few instances where for-loops have been changed to extends.
~~Let's see what the performance impact is. With a bit more refactoring, we might be able to get rid of some of the additional sorting -- but the change set is already big enough. Unless there's a performance impact, I'd like to do further changes in subsequent PRs.~~
Performance does not seem to be negatively affected ([perf-run here](https://github.com/rust-lang/rust/pull/106977#issuecomment-1396776699)).
Part of [MCP 533](https://github.com/rust-lang/compiler-team/issues/533).
r? `@ghost`
Don't wf-check non-local RPITs
We were using `ty::is_impl_trait_defn(..).is_none()` to check if we need to add WF obligations for an opaque type.
This is *supposed* to be checking if the type is a TAIT, since RPITs' wfness is implied by wf checking its parent item, but since `is_impl_trait_defn` returns `None` for non-local RPIT and async futures, we unnecessarily consider wf predicates for an RPIT if it is coming from a foreign crate.
Fixes#107036
r? `@oli-obk` but feel free to reassign
even more unify Projection/Opaque handling in region outlives code
edit: This continues ate the same pace as #106829. New changes are described in https://github.com/rust-lang/rust/pull/106910#issuecomment-1383251254.
~This touches `OutlivesBound`, `Component`, `GenericKind` enums.~
r? `@oli-obk` (because of overlap with #95474)
document + UI test `E0208` and make its output more user-friendly
Cleans up `E0208`'s output a lot. It could actually be useful for someone learning about variance now. I also added a UI test for it in `tests/ui/error-codes/` and wrote some docs for it.
r? `@GuillaumeGomez` another error code, can't be bothered to find the issue :P. Obviously there's some compiler stuff, so you'll have to hand it off.
Part of https://github.com/rust-lang/rust/issues/61137.
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.
Switch to `EarlyBinder` for `item_bounds` query
Part of the work to finish #105779 (also see https://github.com/rust-lang/types-team/issues/78).
Several queries `X` have a `bound_X` variant that wraps the output in `EarlyBinder`. This adds `EarlyBinder` to the return type of the `item_bounds` query and removes `bound_item_bounds`.
r? `@lcnr`
Unify `Opaque`/`Projection` handling in region outlives code
They share basically identical paths in most places which are even easier to unify now that they're both `ty::Alias`
r? types
Bump `IMPLIED_BOUNDS_ENTAILMENT` to Deny + ReportNow
https://github.com/rust-lang/rust/pull/105575#issuecomment-1357201969
> and then later in the same cycle increase the lint to `deny` and change it to `FutureCompatReportNow` in this nightly cycle.
r? ```@lcnr``` when they're back from holiday 😄
Revert "Make nested RPITIT inherit the parent opaque's generics."
This reverts commit e2d41f4c97, and adjusts the `tests/ui/async-await/in-trait/nested-rpit.rs` test.
r? `@cjgillot`
fixes#106332, manually verified because it had no minimization :/
reopens#105197
cc #106729
Remove `<dyn AstConv<'tcx>>::fun(c, ...)` calls in favour of `c.astconv().fun(...)`
This removes the need for <>><><><<>> dances and makes the code a bit nicer.
Not sure if `astconv` is the best name though, maybe someone has a better idea?
Move `check_region_obligations_and_report_errors` to `TypeErrCtxt`
Makes sense for this function to live with its sibling `resolve_regions_and_report_errors`, around which it's basically just a wrapper.
Rework `Bounds` collection
I think it's weird for the `Bounds` struct in astconv to store its predicates *almost* converted into real predicates... so we do this eagerly, instead of lazily.
We delay projection normalization to further stages in order to
register user type annotations before normalization in HIR typeck.
There are two consumers of astconv: ItemCtxt and FnCtxt.
The former already expects unnormalized types from astconv, see its
AstConv trait impl.
The latter needs `RawTy` for a cleaner interface.
Unfortunately astconv still needs the normalization machinery in
order to resolve enum variants that have projections in the self type,
e.g. `<<T as Trait>::Assoc>::StructVariant {}`.
This is why `AstConv::normalize_ty_2` is necessary.
Add help diag. for `const = Enum` missing braces around `Enum`
Previously it was not clear why this errored or if it was even supported, as there was no diagnostic that suggested wrapping it in braces.
Thus, add a simple diagnostic that suggests wrapping enum variants in braces.
Fixes#105927
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.
Suggest `impl Fn*` and `impl Future` in `-> _` return suggestions
Follow-up to #106172, only the last commit is relevant. Can rebase once that PR is landed for easier review.
Suggests `impl Future` and `impl Fn{,Mut,Once}` in `-> _` return suggestions.
r? `@estebank`
Previously it was not clear why this errored or if it was even supported, as there was no
diagnostic that suggested wrapping it in braces.
Thus, add a simple diagnostic that suggests wrapping enum variants in braces.
Some `compare_method` tweaks
1. Make some of the comparison functions' names more regular
2. Reduce pub scope of some of the things in `compare_method`
~3. Remove some unnecessary opaque type handling code -- `InferCtxt` already is in a mode that doesn't define opaque types~
* moved to a different PR
4. Bubble up `ErrorGuaranteed` for region constraint errors in `compare_method` - Improves a redundant error message in one unit test.
5. Move the `compare_method` module to have a more general name, since it's more like `compare_impl_item` :)
6. Rename `collect_trait_impl_trait_tys`
Rename `assert_uninit_valid` intrinsic
It's not about "uninit" anymore but about "filling with 0x01 bytes" so the name should at least try to reflect that.
This is actually not fully correct though, as it does still panic for all uninit with `-Zstrict-init-checks`. I'm not sure what the best way is to deal with that not causing confusion. I guess we could just remove the flag? I don't think having it makes a lot of sense anymore with the direction that we have chose to go. It could be relevant again if #100423 lands so removing it may be a bit over eager.
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.
Add `IMPLIED_BOUNDS_ENTAILMENT` lint
Implements a lint (#105572) version of the hard-error introduced in #105483. Context is in that PR.
r? `@lcnr`
cc `@oli-obk` who had asked for this to be a lint first
Not sure if this needs to be an FCP, since it's a lint for now.
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.
always use `anonymize_bound_vars`
Unless this is perf-sensitive, it's probably best to always use one anonymize function that does the right thing for all bound vars.
r? types
Ensure async trait impls are async (or otherwise return an opaque type)
As a workaround for the full `#[refine]` semantics not being implemented
yet, forbit returning a concrete future type like `Box<dyn Future>` or a
manually implemented Future.
`-> impl Future` is still permitted; while that can also cause
accidental refinement, that's behind a different feature gate
(`return_position_impl_trait_in_trait`) and that problem exists
regardless of whether the trait method is async, so will have to be
solved more generally.
Fixes https://github.com/rust-lang/rust/issues/102745
As a workaround for the full `#[refine]` semantics not being implemented
yet, forbit returning a concrete future type like `Box<dyn Future>` or a
manually implemented Future.
`-> impl Future` is still permitted; while that can also cause
accidental refinement, that's behind a different feature gate
(`return_position_impl_trait_in_trait`) and that problem exists
regardless of whether the trait method is async, so will have to be
solved more generally.
Fixes#102745
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`
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 :/
Add LLVM KCFI support to the Rust compiler
This PR adds LLVM Kernel Control Flow Integrity (KCFI) support to the Rust compiler. It initially provides forward-edge control flow protection for operating systems kernels for Rust-compiled code only by aggregating function pointers in groups identified by their return and parameter types. (See llvm/llvm-project@cff5bef.)
Forward-edge control flow protection for C or C++ and Rust -compiled code "mixed binaries" (i.e., for when C or C++ and Rust -compiled code share the same virtual address space) will be provided in later work as part of this project by identifying C char and integer type uses at the time types are encoded (see Type metadata in the design document in the tracking issue #89653).
LLVM KCFI can be enabled with -Zsanitizer=kcfi.
Thank you again, `@bjorn3,` `@eddyb,` `@nagisa,` and `@ojeda,` for all the help!
This commit adds LLVM Kernel Control Flow Integrity (KCFI) support to
the Rust compiler. It initially provides forward-edge control flow
protection for operating systems kernels for Rust-compiled code only by
aggregating function pointers in groups identified by their return and
parameter types. (See llvm/llvm-project@cff5bef.)
Forward-edge control flow protection for C or C++ and Rust -compiled
code "mixed binaries" (i.e., for when C or C++ and Rust -compiled code
share the same virtual address space) will be provided in later work as
part of this project by identifying C char and integer type uses at the
time types are encoded (see Type metadata in the design document in the
tracking issue #89653).
LLVM KCFI can be enabled with -Zsanitizer=kcfi.
Co-authored-by: bjorn3 <17426603+bjorn3@users.noreply.github.com>
This ensures that the error is printed even for unused variables,
as well as unifying the handling between the LLVM and GCC backends.
This also fixes unusual behavior around exported Rust-defined variables
with linkage attributes. With the previous behavior, it appears to be
impossible to define such a variable such that it can actually be imported
and used by another crate. This is because on the importing side, the
variable is required to be a pointer, but on the exporting side, the
type checker rejects static variables of pointer type because they do
not implement `Sync`. Even if it were possible to import such a type, it
appears that code generation on the importing side would add an unexpected
additional level of pointer indirection, which would break type safety.
This highlighted that the semantics of linkage on Rust-defined variables
is different to linkage on foreign items. As such, we now model the
difference with two different codegen attributes: linkage for Rust-defined
variables, and import_linkage for foreign items.
This change gives semantics to the test
src/test/ui/linkage-attr/auxiliary/def_illtyped_external.rs which was
previously expected to fail to compile. Therefore, convert it into a
test that is expected to successfully compile.
The update to the GCC backend is speculative and untested.
Avoid some `InferCtxt::build` calls
Either because we're inside of an `InferCtxt` already, or because we're not in a place where we'd ever see inference vars.
r? types
Rollup of 6 pull requests
Successful merges:
- #101975 (Suggest to use . instead of :: when accessing a method of an object)
- #105141 (Fix ICE on invalid variable declarations in macro calls)
- #105224 (Properly substitute inherent associated types.)
- #105236 (Add regression test for #47814)
- #105247 (Use parent function WfCheckingContext to check RPITIT.)
- #105253 (Update a couple of rustbuild deps)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Remove drop order twist of && and || and make them associative
Previously a short circuiting binop chain (chain of && or ||s) would drop the temporaries created by the first element after all the other elements, and otherwise follow evaluation order. So `f(1).g() && f(2).g() && f(3).g() && f(4).g()` would drop the temporaries in the order `2,3,4,1`. This made `&&` and `||` non-associative regarding drop order. In other words, adding ()'s to the expression would change drop order: `f(1).g() && (f(2).g() && f(3).g()) && f(4).g()` for example would drop in the order `3,2,4,1`.
As, except for the bool result, there is no data returned by the sub-expressions of the short circuiting binops, we can safely discard of any temporaries created by the sub-expr. Previously, code was already putting the rhs's into terminating scopes, but missed it for the lhs's.
This commit addresses this "twist". We now also put the lhs into a terminating scope. The drop order of the above expressions becomes `1,2,3,4`.
There might be code relying on the current order, and therefore I'd recommend doing a crater run to gauge the impact. I'd argue that such code is already quite wonky as it is one `foo() &&` addition away from breaking. ~~For the impact, I don't expect any *build* failures, as the compiler gets strictly more tolerant: shortening the lifetime of temporaries only expands the list of programs the compiler accepts as valid. There might be *runtime* failures caused by this change however.~~ Edit: both build and runtime failures are possible, e.g. see the example provided by dtolnay [below](https://github.com/rust-lang/rust/pull/103293#issuecomment-1285341113). Edit2: the crater run has finished and [results](https://github.com/rust-lang/rust/pull/103293#issuecomment-1292275203) are that there is only one build failure which is easy to fix with a +/- 1 line diff.
I've included a testcase that now compiles thanks to this patch.
The breakage is also limited to drop order relative to conditionals in the && chain: that is, in code like this:
```Rust
let hello = foo().hi() && bar().world();
println!("hi");
```
we already drop the temporaries of `foo().hi()` before we reach "hi".
I'd ideally have this PR merged before let chains are stabilized. If this PR is taking too long, I'd love to have a more restricted version of this change limited to `&&`'s in let chains: the `&&`'s of such chains are quite special anyways as they accept `let` bindings, in there the `&&` is therefore more a part of the "if let chain" construct than a construct of its own.
Fixes#103107
Status: waiting on [this accepted FCP](https://github.com/rust-lang/rust/pull/103293#issuecomment-1293411354) finishing.
This avoids creation of a terminating scope in
chains that contain both && and ||, because
also there we know that a terminating scope is
not neccessary: all the chain members are already
in such terminating scopes.
Also add a mixed && / || test.
Previously a short circuiting && chain would drop the
first element after all the other elements, and otherwise
follow evaluation order, so code like:
f(1).g() && f(2).g() && f(3).g() && f(4).g()
would drop the temporaries in the order 2,3,4,1. This made
&& and || non-associative regarding drop order, so
adding ()'s to the expression would change drop order:
f(1).g() && (f(2).g() && f(3).g()) && f(4).g()
for example would drop in the order 3,2,4,1.
As, except for the bool result, there is no data returned
by the sub-expressions of the short circuiting binops,
we can safely discard of any temporaries created by the
sub-expr. Previously, code was already putting the rhs's
into terminating scopes, but missed it for the lhs's.
This commit addresses this "twist". In the expression,
we now also put the lhs into a terminating scope.
The drop order for the above expressions is 1,2,3,4
now.