the behavior of the type system not only depends on the current
assumptions, but also the currentnphase of the compiler. This is
mostly necessary as we need to decide whether and how to reveal
opaque types. We track this via the `TypingMode`.
Check `use<..>` in RPITIT for refinement
`#![feature(precise_capturing_in_traits)]` allows users to write `+ use<>` bounds on RPITITs to control what lifetimes are captured by the RPITIT.
Since RPITITs currently also warn for refinement in implementations, this PR extends that refinement check for cases where we *undercapture* in an implementation, since that may be indirectly "promising" a more relaxed outlives bound than the impl author intended.
For an opaque to be refining, we need to capture *fewer* parameters than those mentioned in the captured params of the trait. For example:
```
trait TypeParam<T> {
fn test() -> impl Sized;
}
// Indirectly capturing a lifetime param through a type param substitution.
impl<'a> TypeParam<&'a ()> for i32 {
fn test() -> impl Sized + use<> {}
//~^ WARN impl trait in impl method captures fewer lifetimes than in trait
}
```
Since the opaque in the method (implicitly) captures `use<Self, T>`, and `Self = i32, T = &'a ()` in the impl, we must mention `'a` in our `use<..>` on the impl.
Tracking:
* https://github.com/rust-lang/rust/issues/130044
Deny capturing late-bound ty/const params in nested opaques
First, this reverts a7f609504c. I can't exactly remember why I approved this specific bit of https://github.com/rust-lang/rust/pull/132466; specifically, I don't know that the purpose of that commit is, and afaict we will never have an opaque that captures late-bound params through a const because opaques can't be used inside of anon consts. Am I missing something `@cjgillot?` Since I can't see a case where this matters, and no tests seem to fail.
The second commit adds a `deny_late_regions: bool` to distinguish `Scope::LateBoundary` which should deny *any* late-bound params or just ty/consts. Then, when resolving opaques we wrap ourselves in a `Scope::LateBoundary { deny_late_regions: false }` so that we deny late-bound ty/const, which fixes a bunch of ICEs that all vaguely look like `impl for<T> Trait<Assoc = impl OtherTrait<T>>`.
I guess this could be achieved other ways; for example, with a different scope kind, or maybe we could just reuse `Scope::Opaque`. But this seems a bit more verbose. I'm open to feedback anyways.
Fixes#131535Fixes#131637Fixes#132530
I opted to remove those crashes tests ^ without adding them as regular tests, since they're basically triggering uninteresting late-bound ICEs far off in the trait solver, and the reason that existing tests such as `tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.rs` don't ICE are kinda just coincidental (i.e. due to a missing impl block). I don't really feel motivated to add random permutations to tests just to exercise non-lifetime binders.
r? cjgillot
Get rid of `check_opaque_type_well_formed`
Instead, replicate it by improving the span of the opaque in `check_opaque_meets_bounds`.
This has two consequences:
1. We now prefer "concrete type differs" errors, since we'll hit those first before we check the opaque is WF.
2. Spans have gotten slightly worse.
Specifically, (2.) could be improved by adding a new obligation cause that explains that the definition's environment has stronger assumptions than the declaration.
r? lcnr
Remove unnecessary pub enum glob-imports from `rustc_middle::ty`
We used to have an idiom in the compiler where we'd prefix or suffix all the variants of an enum, for example `BoundRegionKind`, with something like `Br`, and then *glob-import* that enum variant directly.
`@noratrieb` brought this up, and I think that it's easier to read when we just use the normal style `EnumName::Variant`.
This PR is a bit large, but it's just naming.
The only somewhat opinionated change that this PR does is rename `BorrowKind::Imm` to `BorrowKind::Immutable` and same for the other variants. I think these enums are used sparingly enough that the extra length is fine.
r? `@noratrieb` or reassign
find the generic container rather than simply looking up for the assoc with const arg
Fixes#132534
This issue is caused by mismatched generic parameters. Previously, it tried to find `T` in `trait X`, but after this change, it will find `T` in `fn a`.
r? `@compiler-errors` as this assertion was introduced by you.
Use backticks instead of single quotes for library feature names in diagnostics
This PR changes the text of library feature errors for using unstable or body-unstable items. Displaying library feature names in backticks is consistent with other diagnostics (e.g. those from `rustc_passes`) and with the `reason`s on unstable attributes in the library. Additionally, this simplifies diagnostics when supporting multiple unstable attributes on items (see #131824) since `DiagSymbolList` also displays symbols using backticks.
compiler: Directly use rustc_abi almost everywhere
Use rustc_abi instead of rustc_target where applicable. This is mostly described by the following substitutions:
```rust
match path_substring {
rustc_target::spec::abi::Abi => rustc_abi::ExternAbi,
rustc_target::abi::call => rustc_target::callconv,
rustc_target::abi => rustc_abi,
}
```
A number of spot-fixes make that not quite the whole story.
The main exception is in 33edc68 where I get a lot more persnickety about how things are imported, especially in `rustc_middle::ty::layout`, not just from where. This includes putting an end to a reexport of `rustc_middle::ty::ReprOptions`, for the same reason that the rest of this change is happening: reexports mostly confound things.
This notably omits rustc_passes and the ast crates, as I'm still examining a question I have about how they do stability checking of `extern "Abi"` strings and if I can simplify their logic. The rustc_abi and rustc_target crates also go untouched because they will be entangled in that cleanup.
r? compiler-errors
This is consistent with all other diagnostics I could find containing
features and enables the use of `DiagSymbolList` for generalizing
diagnostics for unstable library features to multiple features.
Some where clause lowering simplifications
Rename `PredicateFilter::SelfThatDefines` to `PredicateFilter::SelfTraitThatDefines` to make it clear that it's only concerned with converting *traits*, and make it do a bit less work when converting bounds.
Also, make the predicate filter matching in `probe_ty_param_bounds_in_generics` explicit, and simply the args it receives a bit.
Fix validation when lowering `?` trait bounds
Pass the unlowered (`rustc_hir`) polarity to `lower_poly_trait_ref`.
This allows us to actually *validate* that generic args are actually valid on `?Trait` paths. This actually regressed in #113671 because that PR changed the behavior where we were inadvertently re-lowering paths as `BoundPolarity::Positive`, which was also coincidentally the only place we were enforcing the generics on `?Trait` paths were correct.
Try to point out when edition 2024 lifetime capture rules cause borrowck issues
Lifetime capture rules in 2024 are modified to capture more lifetimes, which sometimes lead to some non-local borrowck errors. This PR attempts to link these back together with a useful note pointing out the capture rule changes.
This is not a blocking concern, but I'd appreciate feedback (though, again, I'd like to stress that I don't want to block this PR on this): I'm worried about this note drowning in the sea of other diagnostics that borrowck emits. I was tempted to change the level of the note to `.span_warn` just so it would show up in a different color. Thoughts?
Fixes#130545
Opening as a draft first since it's stacked on #131183.
r? `@ghost`
Make sure `type_param_predicates` resolves correctly for RPITIT
After #132194, we end up lowering the item bounds for an RPITIT in an `ItemCtxt` whose def id is the *synthetic GAT*, not the opaque type from the HIR.
This means that when we're resolving a shorthand projection like `T::Assoc`, we call the `type_param_predicates` function with the `item_def_id` of the *GAT* and not the opaque. That function operates on the HIR, and is not designed to work with the `Node::Synthetic` that gets fed for items synthesized by the compiler...
This PR reuses the trick we use elsewhere in lowering, where we intercept whether an item comes from RPITIT lowering, and forwards the query off to the correct item.
Fixes#132372
Remap impl-trait lifetimes on HIR instead of AST lowering
Current AST->HIR lowering goes out of its way to remap lifetimes for opaque types. This is complicated and leaks into upstream and downstream code.
This PR stops trying to be clever during lowering, and prefers to do this remapping during the HIR->ty lowering. The remapping computation easily fits into the bound var resolution code. Its result can be used in by `generics_of` and `hir_ty_lowering::new_opaque` to add the proper parameters and arguments.
See an example on the doc for query `opaque_captured_lifetimes`.
Based on https://github.com/rust-lang/rust/pull/129244/
Fixes https://github.com/rust-lang/rust/issues/125249
Fixes https://github.com/rust-lang/rust/issues/126850
cc `@compiler-errors` `@spastorino`
r? `@petrochenkov`