Skip to content

Commit 5d753ab

Browse files
committed
have better explanation for relate_types
1 parent 6f0c5ee commit 5d753ab

File tree

13 files changed

+40
-34
lines changed

13 files changed

+40
-34
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -716,11 +716,9 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
716716
}
717717
PlaceTy::from_ty(fty)
718718
}
719-
ProjectionElem::Subtype(_) => PlaceTy::from_ty(Ty::new_error_with_message(
720-
tcx,
721-
self.last_span,
722-
"ProjectionElem::Subtype shouldn't exist in borrowck",
723-
)),
719+
ProjectionElem::Subtype(_) => {
720+
bug!("ProjectionElem::Subtype shouldn't exist in borrowck")
721+
}
724722
ProjectionElem::OpaqueCast(ty) => {
725723
let ty = self.sanitize_type(place, ty);
726724
let ty = self.cx.normalize(ty, location);

compiler/rustc_codegen_cranelift/src/value_and_place.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ impl<'tcx> CPlace<'tcx> {
674674
}
675675
}
676676

677-
/// Used for `ProjectionElem::Subtype`, ty has to be monomorphized before
677+
/// Used for `ProjectionElem::Subtype`, `ty` has to be monomorphized before
678678
/// passed on.
679679
pub(crate) fn place_transmute_type(
680680
self,

compiler/rustc_const_eval/src/util/compare_types.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ pub fn is_equal_up_to_subtyping<'tcx>(
3030

3131
/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
3232
///
33-
/// For almost all of the use cases variance should be `Covariant`,
34-
/// in `MirPhase` >= `MirPhase::Runtime(RuntimePhase::Initial` variance should
35-
/// be `Invariant`.
33+
/// When validating assignments, the variance should be `Covariant`. When checking
34+
/// during `MirPhase` >= `MirPhase::Runtime(RuntimePhase::Initial)` variance should be `Invariant`
35+
/// because we want to check for type equality.
3636
///
3737
/// This mostly ignores opaque types as it can be used in constraining contexts
3838
/// while still computing the final underlying type.

compiler/rustc_middle/src/mir/pretty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,7 @@ fn post_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) ->
11271127
write!(fmt, " as {ty})")?;
11281128
}
11291129
ProjectionElem::Subtype(ty) => {
1130-
write!(fmt, "as {ty})")?;
1130+
write!(fmt, " as subtype {ty})")?;
11311131
}
11321132
ProjectionElem::Downcast(Some(name), _index) => {
11331133
write!(fmt, " as {name})")?;

compiler/rustc_middle/src/mir/syntax.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1077,9 +1077,12 @@ pub enum ProjectionElem<V, T> {
10771077
OpaqueCast(T),
10781078

10791079
/// A `Subtype(T)` projection is applied to any `StatementKind::Assign` where
1080-
/// type of lvalue doesn't match type of rvalue, primary goal being making subtyping
1080+
/// type of lvalue doesn't match the type of rvalue, the primary goal is making subtyping
10811081
/// explicit during optimizations and codegen.
10821082
///
1083+
/// This projection doesn't impact the runtime behavior of the program except for potentially changing
1084+
/// some type metadata of the interpreter or codegen backend.
1085+
///
10831086
/// This goal is achieved with mir_transform pass `Subtyper`, which runs right after
10841087
/// borrowchecker, as we only care about subtyping that can affect trait selection and
10851088
/// `TypeId`.

compiler/rustc_middle/src/mir/tcx.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ impl<'tcx> PlaceTy<'tcx> {
6969
param_env: ty::ParamEnv<'tcx>,
7070
elem: &ProjectionElem<V, T>,
7171
mut handle_field: impl FnMut(&Self, FieldIdx, T) -> Ty<'tcx>,
72-
mut handle_opaque_cast: impl FnMut(&Self, T) -> Ty<'tcx>,
72+
mut handle_opaque_cast_and_subtype: impl FnMut(&Self, T) -> Ty<'tcx>,
7373
) -> PlaceTy<'tcx>
7474
where
7575
V: ::std::fmt::Debug,
@@ -110,8 +110,12 @@ impl<'tcx> PlaceTy<'tcx> {
110110
PlaceTy { ty: self.ty, variant_index: Some(index) }
111111
}
112112
ProjectionElem::Field(f, fty) => PlaceTy::from_ty(handle_field(&self, f, fty)),
113-
ProjectionElem::OpaqueCast(ty) => PlaceTy::from_ty(handle_opaque_cast(&self, ty)),
114-
ProjectionElem::Subtype(_) => PlaceTy::from_ty(self.ty),
113+
ProjectionElem::OpaqueCast(ty) => {
114+
PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty))
115+
}
116+
ProjectionElem::Subtype(ty) => {
117+
PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty))
118+
}
115119
};
116120
debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer);
117121
answer

compiler/rustc_mir_dataflow/src/move_paths/builder.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,6 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
112112
let mut union_path = None;
113113

114114
for (place_ref, elem) in data.rev_lookup.un_derefer.iter_projections(place.as_ref()) {
115-
// We don't care creating `MovePath` for `ProjectionElem::Subtype(T)` because it's for debugging/validating
116-
// purposes it's movement doesn't affect anything.
117115
let body = self.builder.body;
118116
let tcx = self.builder.tcx;
119117
let place_ty = place_ref.ty(body, tcx).ty;
@@ -229,8 +227,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
229227
}
230228
_ => bug!("Unexpected type {place_ty:#?}"),
231229
},
232-
// `OpaqueCast` only transmutes the type, so no moves there and
233-
// `Downcast` only changes information about a `Place` without moving
230+
// `OpaqueCast`:Only transmutes the type, so no moves there.
231+
// `Downcast` :Only changes information about a `Place` without moving.
232+
// `Subtype` :Only transmutes the type, so moves.
234233
// So it's safe to skip these.
235234
ProjectionElem::OpaqueCast(_)
236235
| ProjectionElem::Subtype(_)

compiler/rustc_mir_transform/src/add_subtyping_projections.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,31 @@ impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> {
2424
rvalue: &mut Rvalue<'tcx>,
2525
location: Location,
2626
) {
27-
let place_ty = place.ty(self.local_decls, self.tcx);
27+
let mut place_ty = place.ty(self.local_decls, self.tcx).ty;
2828
let mut rval_ty = rvalue.ty(self.local_decls, self.tcx);
29-
if place_ty.ty != rval_ty {
30-
// Not erasing this causes `Free Regions` errors in validator,
31-
// when rval is `ReStatic`.
32-
rval_ty = self.tcx.erase_regions_ty(rval_ty);
29+
// Not erasing this causes `Free Regions` errors in validator,
30+
// when rval is `ReStatic`.
31+
rval_ty = self.tcx.erase_regions_ty(rval_ty);
32+
place_ty = self.tcx.erase_regions(place_ty);
33+
if place_ty != rval_ty {
3334
let temp = self
3435
.patcher
3536
.new_temp(rval_ty, self.local_decls[place.as_ref().local].source_info.span);
3637
let new_place = Place::from(temp);
3738
self.patcher.add_assign(location, new_place, rvalue.clone());
38-
let subtyped =
39-
new_place.project_deeper(&[ProjectionElem::Subtype(place_ty.ty)], self.tcx);
39+
let subtyped = new_place.project_deeper(&[ProjectionElem::Subtype(place_ty)], self.tcx);
4040
*rvalue = Rvalue::Use(Operand::Move(subtyped));
4141
}
4242
}
4343
}
4444

45+
// Aim here is to do this kind of transformation:
46+
//
47+
// let place: place_ty = rval;
48+
// // gets transformed to
49+
// let temp: rval_ty = rval;
50+
// let place: place_ty = temp as place_ty;
51+
//
4552
pub fn subtype_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
4653
let patch = MirPatch::new(body);
4754
let mut checker = SubTypeChecker { tcx, patcher: patch, local_decls: &body.local_decls };

src/tools/stable-mir-dev

-1
This file was deleted.

tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
- _4 = g() -> [return: bb1, unwind unreachable];
3838
+ StorageLive(_5);
3939
+ _5 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
40-
+ _4 = move (_5as {generator@$DIR/inline_generator.rs:16:5: 16:8});
40+
+ _4 = move (_5 as subtype {generator@$DIR/inline_generator.rs:16:5: 16:8});
4141
+ StorageDead(_5);
4242
+ _3 = &mut _4;
4343
+ _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}> { pointer: move _3 };

tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
- bb1: {
4141
+ StorageLive(_5);
4242
+ _5 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
43-
+ _4 = move (_5as {generator@$DIR/inline_generator.rs:16:5: 16:8});
43+
+ _4 = move (_5 as subtype {generator@$DIR/inline_generator.rs:16:5: 16:8});
4444
+ StorageDead(_5);
4545
_3 = &mut _4;
4646
- _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new(move _3) -> [return: bb2, unwind: bb5];

tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir

+1-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ fn main() -> () {
2222
let _24: i32;
2323
let mut _26: *const i32;
2424
let _27: ();
25-
let mut _29: for<'a> fn(&'a i32) -> &'a i32;
2625
scope 1 {
2726
debug x => _1;
2827
let _3: &mut i32;
@@ -106,8 +105,7 @@ fn main() -> () {
106105
StorageLive(_14);
107106
_14 = {closure@main::{closure#0}};
108107
Retag(_14);
109-
_29 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Normal)));
110-
_13 = move (_29as for<'a> fn(&'a i32) -> &'a i32);
108+
_13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Normal)));
111109
StorageDead(_14);
112110
StorageLive(_15);
113111
StorageLive(_16);

tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir

+1-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ fn main() -> () {
2222
let _24: i32;
2323
let mut _26: *const i32;
2424
let _27: ();
25-
let mut _29: for<'a> fn(&'a i32) -> &'a i32;
2625
scope 1 {
2726
debug x => _1;
2827
let _3: &mut i32;
@@ -106,8 +105,7 @@ fn main() -> () {
106105
StorageLive(_14);
107106
_14 = {closure@main::{closure#0}};
108107
Retag(_14);
109-
_29 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Normal)));
110-
_13 = move (_29as for<'a> fn(&'a i32) -> &'a i32);
108+
_13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Normal)));
111109
StorageDead(_14);
112110
StorageLive(_15);
113111
StorageLive(_16);

0 commit comments

Comments
 (0)