Skip to content

Commit 289a23e

Browse files
committed
do not emit OpaqueCast projections with -Znext-solver
1 parent 15c4cce commit 289a23e

File tree

5 files changed

+48
-34
lines changed

5 files changed

+48
-34
lines changed

compiler/rustc_hir_typeck/src/expr_use_visitor.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,16 +1502,21 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
15021502
let mut projections = base_place.place.projections;
15031503

15041504
let node_ty = self.cx.typeck_results().node_type(node);
1505-
// Opaque types can't have field projections, but we can instead convert
1506-
// the current place in-place (heh) to the hidden type, and then apply all
1507-
// follow up projections on that.
1508-
if node_ty != place_ty
1509-
&& self
1510-
.cx
1511-
.try_structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), place_ty)
1512-
.is_impl_trait()
1513-
{
1514-
projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty });
1505+
if !self.cx.tcx().next_trait_solver_globally() {
1506+
// Opaque types can't have field projections, but we can instead convert
1507+
// the current place in-place (heh) to the hidden type, and then apply all
1508+
// follow up projections on that.
1509+
if node_ty != place_ty
1510+
&& self
1511+
.cx
1512+
.try_structurally_resolve_type(
1513+
self.cx.tcx().hir_span(base_place.hir_id),
1514+
place_ty,
1515+
)
1516+
.is_impl_trait()
1517+
{
1518+
projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty });
1519+
}
15151520
}
15161521
projections.push(Projection { kind, ty });
15171522
PlaceWithHirId::new(node, base_place.place.base_ty, base_place.place.base, projections)

compiler/rustc_middle/src/hir/place.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ pub enum ProjectionKind {
4040

4141
/// A conversion from an opaque type to its hidden type so we can
4242
/// do further projections on it.
43+
///
44+
/// This is unused if `-Znext-solver` is enabled.
4345
OpaqueCast,
4446
}
4547

compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,8 @@ pub enum ProjectionElem<V, T> {
12421242

12431243
/// Like an explicit cast from an opaque type to a concrete type, but without
12441244
/// requiring an intermediate variable.
1245+
///
1246+
/// This is unused with `-Znext-solver`.
12451247
OpaqueCast(T),
12461248

12471249
/// A transmute from an unsafe binder to the type that it wraps. This is a projection

compiler/rustc_mir_build/src/builder/matches/match_pair.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,18 +101,21 @@ impl<'tcx> MatchPairTree<'tcx> {
101101
place_builder = resolved;
102102
}
103103

104-
// Only add the OpaqueCast projection if the given place is an opaque type and the
105-
// expected type from the pattern is not.
106-
let may_need_cast = match place_builder.base() {
107-
PlaceBase::Local(local) => {
108-
let ty =
109-
Place::ty_from(local, place_builder.projection(), &cx.local_decls, cx.tcx).ty;
110-
ty != pattern.ty && ty.has_opaque_types()
104+
if !cx.tcx.next_trait_solver_globally() {
105+
// Only add the OpaqueCast projection if the given place is an opaque type and the
106+
// expected type from the pattern is not.
107+
let may_need_cast = match place_builder.base() {
108+
PlaceBase::Local(local) => {
109+
let ty =
110+
Place::ty_from(local, place_builder.projection(), &cx.local_decls, cx.tcx)
111+
.ty;
112+
ty != pattern.ty && ty.has_opaque_types()
113+
}
114+
_ => true,
115+
};
116+
if may_need_cast {
117+
place_builder = place_builder.project(ProjectionElem::OpaqueCast(pattern.ty));
111118
}
112-
_ => true,
113-
};
114-
if may_need_cast {
115-
place_builder = place_builder.project(ProjectionElem::OpaqueCast(pattern.ty));
116119
}
117120

118121
let place = place_builder.try_to_place(cx);

compiler/rustc_mir_transform/src/post_analysis_normalize.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,22 @@ impl<'tcx> MutVisitor<'tcx> for PostAnalysisNormalizeVisitor<'tcx> {
3939
_context: PlaceContext,
4040
_location: Location,
4141
) {
42-
// Performance optimization: don't reintern if there is no `OpaqueCast` to remove.
43-
if place.projection.iter().all(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) {
44-
return;
42+
if !self.tcx.next_trait_solver_globally() {
43+
// `OpaqueCast` projections are only needed if there are opaque types on which projections
44+
// are performed. After the `PostAnalysisNormalize` pass, all opaque types are replaced with their
45+
// hidden types, so we don't need these projections anymore.
46+
//
47+
// Performance optimization: don't reintern if there is no `OpaqueCast` to remove.
48+
if place.projection.iter().any(|elem| matches!(elem, ProjectionElem::OpaqueCast(_))) {
49+
place.projection = self.tcx.mk_place_elems(
50+
&place
51+
.projection
52+
.into_iter()
53+
.filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_)))
54+
.collect::<Vec<_>>(),
55+
);
56+
};
4557
}
46-
// `OpaqueCast` projections are only needed if there are opaque types on which projections
47-
// are performed. After the `PostAnalysisNormalize` pass, all opaque types are replaced with their
48-
// hidden types, so we don't need these projections anymore.
49-
place.projection = self.tcx.mk_place_elems(
50-
&place
51-
.projection
52-
.into_iter()
53-
.filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_)))
54-
.collect::<Vec<_>>(),
55-
);
5658
self.super_place(place, _context, _location);
5759
}
5860

0 commit comments

Comments
 (0)