Skip to content

Commit 67e2358

Browse files
authored
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```
2 parents cecc7a4 + c85b5fc commit 67e2358

File tree

8 files changed

+52
-35
lines changed

8 files changed

+52
-35
lines changed

compiler/rustc_hir_typeck/src/expr_use_visitor.rs

+15-10
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

+2
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

+2
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

+14-11
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

+15-13
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

tests/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//@ compile-flags: --crate-type=lib
22
//@ edition: 2021
3-
//@ rustc-env:RUST_BACKTRACE=0
43
//@ check-pass
54

65
// tracked in https://github.com/rust-lang/rust/issues/96572

tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//@ revisions: current next
2+
//@ [next] compile-flags: -Znext-solver
13
//@ build-pass
24
//@ edition: 2021
35

tests/ui/type-alias-impl-trait/tait-normalize.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//@ revisions: current next
2+
//@ [next] compile-flags: -Znext-solver
13
//@ check-pass
24

35
#![feature(type_alias_impl_trait)]

0 commit comments

Comments
 (0)