Rollup merge of #139902 - lcnr:no-opaque-cast-projection, r=oli-obk
do not emit `OpaqueCast` projections with `-Znext-solver` We normalize opaque types in their defining scope if the new solver is enabled. This means projections do not contain any 'revealable' opaque types we need to worry about. We either have a type which has been normalized by writeback or we need to normalize it anyways. r? ```@compiler-errors``` ```@oli-obk```
This commit is contained in:
commit
67e2358fbb
8 changed files with 52 additions and 35 deletions
|
@ -1502,17 +1502,22 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
|
|||
let mut projections = base_place.place.projections;
|
||||
|
||||
let node_ty = self.cx.typeck_results().node_type(node);
|
||||
if !self.cx.tcx().next_trait_solver_globally() {
|
||||
// Opaque types can't have field projections, but we can instead convert
|
||||
// the current place in-place (heh) to the hidden type, and then apply all
|
||||
// follow up projections on that.
|
||||
if node_ty != place_ty
|
||||
&& self
|
||||
.cx
|
||||
.try_structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), place_ty)
|
||||
.try_structurally_resolve_type(
|
||||
self.cx.tcx().hir_span(base_place.hir_id),
|
||||
place_ty,
|
||||
)
|
||||
.is_impl_trait()
|
||||
{
|
||||
projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty });
|
||||
}
|
||||
}
|
||||
projections.push(Projection { kind, ty });
|
||||
PlaceWithHirId::new(node, base_place.place.base_ty, base_place.place.base, projections)
|
||||
}
|
||||
|
|
|
@ -40,6 +40,8 @@ pub enum ProjectionKind {
|
|||
|
||||
/// A conversion from an opaque type to its hidden type so we can
|
||||
/// do further projections on it.
|
||||
///
|
||||
/// This is unused if `-Znext-solver` is enabled.
|
||||
OpaqueCast,
|
||||
}
|
||||
|
||||
|
|
|
@ -1242,6 +1242,8 @@ pub enum ProjectionElem<V, T> {
|
|||
|
||||
/// Like an explicit cast from an opaque type to a concrete type, but without
|
||||
/// requiring an intermediate variable.
|
||||
///
|
||||
/// This is unused with `-Znext-solver`.
|
||||
OpaqueCast(T),
|
||||
|
||||
/// A transmute from an unsafe binder to the type that it wraps. This is a projection
|
||||
|
|
|
@ -101,12 +101,14 @@ impl<'tcx> MatchPairTree<'tcx> {
|
|||
place_builder = resolved;
|
||||
}
|
||||
|
||||
if !cx.tcx.next_trait_solver_globally() {
|
||||
// Only add the OpaqueCast projection if the given place is an opaque type and the
|
||||
// expected type from the pattern is not.
|
||||
let may_need_cast = match place_builder.base() {
|
||||
PlaceBase::Local(local) => {
|
||||
let ty =
|
||||
Place::ty_from(local, place_builder.projection(), &cx.local_decls, cx.tcx).ty;
|
||||
Place::ty_from(local, place_builder.projection(), &cx.local_decls, cx.tcx)
|
||||
.ty;
|
||||
ty != pattern.ty && ty.has_opaque_types()
|
||||
}
|
||||
_ => true,
|
||||
|
@ -114,6 +116,7 @@ impl<'tcx> MatchPairTree<'tcx> {
|
|||
if may_need_cast {
|
||||
place_builder = place_builder.project(ProjectionElem::OpaqueCast(pattern.ty));
|
||||
}
|
||||
}
|
||||
|
||||
let place = place_builder.try_to_place(cx);
|
||||
let mut subpairs = Vec::new();
|
||||
|
|
|
@ -39,13 +39,13 @@ impl<'tcx> MutVisitor<'tcx> for PostAnalysisNormalizeVisitor<'tcx> {
|
|||
_context: PlaceContext,
|
||||
_location: Location,
|
||||
) {
|
||||
// Performance optimization: don't reintern if there is no `OpaqueCast` to remove.
|
||||
if place.projection.iter().all(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) {
|
||||
return;
|
||||
}
|
||||
if !self.tcx.next_trait_solver_globally() {
|
||||
// `OpaqueCast` projections are only needed if there are opaque types on which projections
|
||||
// are performed. After the `PostAnalysisNormalize` pass, all opaque types are replaced with their
|
||||
// hidden types, so we don't need these projections anymore.
|
||||
//
|
||||
// Performance optimization: don't reintern if there is no `OpaqueCast` to remove.
|
||||
if place.projection.iter().any(|elem| matches!(elem, ProjectionElem::OpaqueCast(_))) {
|
||||
place.projection = self.tcx.mk_place_elems(
|
||||
&place
|
||||
.projection
|
||||
|
@ -53,6 +53,8 @@ impl<'tcx> MutVisitor<'tcx> for PostAnalysisNormalizeVisitor<'tcx> {
|
|||
.filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_)))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
};
|
||||
}
|
||||
self.super_place(place, _context, _location);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//@ compile-flags: --crate-type=lib
|
||||
//@ edition: 2021
|
||||
//@ rustc-env:RUST_BACKTRACE=0
|
||||
//@ check-pass
|
||||
|
||||
// tracked in https://github.com/rust-lang/rust/issues/96572
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//@ revisions: current next
|
||||
//@ [next] compile-flags: -Znext-solver
|
||||
//@ build-pass
|
||||
//@ edition: 2021
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//@ revisions: current next
|
||||
//@ [next] compile-flags: -Znext-solver
|
||||
//@ check-pass
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue