about summary refs log tree commit diff
diff options
context:
space:
mode:
authorouz-a <ouz.agz@gmail.com>2023-10-02 11:22:48 +0300
committerMark Rousskov <mark.simulacrum@gmail.com>2023-12-04 09:55:14 -0500
commit63976da0e8dbeecbbe9ad5f74441d5ee48945f32 (patch)
tree1dc2b6c45859ff67612c161d20219c57d810cb32
parent41b0ddd937570fd4117b460dc762a5fa0f7236e8 (diff)
downloadrust-63976da0e8dbeecbbe9ad5f74441d5ee48945f32.tar.gz
rust-63976da0e8dbeecbbe9ad5f74441d5ee48945f32.zip
have better explanation for `relate_types`
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs8
-rw-r--r--compiler/rustc_codegen_cranelift/src/value_and_place.rs2
-rw-r--r--compiler/rustc_const_eval/src/util/compare_types.rs6
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs2
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs5
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs10
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs7
-rw-r--r--compiler/rustc_mir_transform/src/add_subtyping_projections.rs21
m---------src/tools/stable-mir-dev0
-rw-r--r--tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff2
-rw-r--r--tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir4
-rw-r--r--tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir4
13 files changed, 40 insertions, 33 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 2bed014b238..1f383e5333d 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -716,11 +716,9 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
                 }
                 PlaceTy::from_ty(fty)
             }
-            ProjectionElem::Subtype(_) => PlaceTy::from_ty(Ty::new_error_with_message(
-                tcx,
-                self.last_span,
-                "ProjectionElem::Subtype shouldn't exist in borrowck",
-            )),
+            ProjectionElem::Subtype(_) => {
+                bug!("ProjectionElem::Subtype shouldn't exist in borrowck")
+            }
             ProjectionElem::OpaqueCast(ty) => {
                 let ty = self.sanitize_type(place, ty);
                 let ty = self.cx.normalize(ty, location);
diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
index 09033cfb23f..45893a4f3ac 100644
--- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs
+++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
@@ -674,7 +674,7 @@ impl<'tcx> CPlace<'tcx> {
         }
     }
 
-    /// Used for `ProjectionElem::Subtype`, ty has to be monomorphized before
+    /// Used for `ProjectionElem::Subtype`, `ty` has to be monomorphized before
     /// passed on.
     pub(crate) fn place_transmute_type(
         self,
diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs
index dd4c67e8d6b..265ca0c7884 100644
--- a/compiler/rustc_const_eval/src/util/compare_types.rs
+++ b/compiler/rustc_const_eval/src/util/compare_types.rs
@@ -30,9 +30,9 @@ pub fn is_equal_up_to_subtyping<'tcx>(
 
 /// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
 ///
-/// For almost all of the use cases variance should be `Covariant`,
-/// in `MirPhase` >= `MirPhase::Runtime(RuntimePhase::Initial` variance should
-/// be `Invariant`.
+/// When validating assignments, the variance should be `Covariant`. When checking
+/// during `MirPhase` >= `MirPhase::Runtime(RuntimePhase::Initial)` variance should be `Invariant`
+/// because we want to check for type equality.
 ///
 /// This mostly ignores opaque types as it can be used in constraining contexts
 /// while still computing the final underlying type.
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 0a72289f1bb..f032fd29d05 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -1127,7 +1127,7 @@ fn post_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) ->
                 write!(fmt, " as {ty})")?;
             }
             ProjectionElem::Subtype(ty) => {
-                write!(fmt, "as {ty})")?;
+                write!(fmt, " as subtype {ty})")?;
             }
             ProjectionElem::Downcast(Some(name), _index) => {
                 write!(fmt, " as {name})")?;
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index fea7819d545..0b95fdfa1fb 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1077,9 +1077,12 @@ pub enum ProjectionElem<V, T> {
     OpaqueCast(T),
 
     /// A `Subtype(T)` projection is applied to any `StatementKind::Assign` where
-    /// type of lvalue doesn't match type of rvalue, primary goal being making subtyping
+    /// type of lvalue doesn't match the type of rvalue, the primary goal is making subtyping
     /// explicit during optimizations and codegen.
     ///
+    /// This projection doesn't impact the runtime behavior of the program except for potentially changing
+    /// some type metadata of the interpreter or codegen backend.
+    ///
     /// This goal is achieved with mir_transform pass `Subtyper`, which runs right after
     /// borrowchecker, as we only care about subtyping that can affect trait selection and
     /// `TypeId`.
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index c3c08276249..7df25fc5c03 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -69,7 +69,7 @@ impl<'tcx> PlaceTy<'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         elem: &ProjectionElem<V, T>,
         mut handle_field: impl FnMut(&Self, FieldIdx, T) -> Ty<'tcx>,
-        mut handle_opaque_cast: impl FnMut(&Self, T) -> Ty<'tcx>,
+        mut handle_opaque_cast_and_subtype: impl FnMut(&Self, T) -> Ty<'tcx>,
     ) -> PlaceTy<'tcx>
     where
         V: ::std::fmt::Debug,
@@ -110,8 +110,12 @@ impl<'tcx> PlaceTy<'tcx> {
                 PlaceTy { ty: self.ty, variant_index: Some(index) }
             }
             ProjectionElem::Field(f, fty) => PlaceTy::from_ty(handle_field(&self, f, fty)),
-            ProjectionElem::OpaqueCast(ty) => PlaceTy::from_ty(handle_opaque_cast(&self, ty)),
-            ProjectionElem::Subtype(_) => PlaceTy::from_ty(self.ty),
+            ProjectionElem::OpaqueCast(ty) => {
+                PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty))
+            }
+            ProjectionElem::Subtype(ty) => {
+                PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty))
+            }
         };
         debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer);
         answer
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 4447ff0798c..7a5b3585d59 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -112,8 +112,6 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
         let mut union_path = None;
 
         for (place_ref, elem) in data.rev_lookup.un_derefer.iter_projections(place.as_ref()) {
-            // We don't care creating `MovePath` for `ProjectionElem::Subtype(T)` because it's for debugging/validating
-            // purposes it's movement doesn't affect anything.
             let body = self.builder.body;
             let tcx = self.builder.tcx;
             let place_ty = place_ref.ty(body, tcx).ty;
@@ -229,8 +227,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                     }
                     _ => bug!("Unexpected type {place_ty:#?}"),
                 },
-                // `OpaqueCast` only transmutes the type, so no moves there and
-                // `Downcast` only changes information about a `Place` without moving
+                // `OpaqueCast`:Only transmutes the type, so no moves there.
+                // `Downcast`  :Only changes information about a `Place` without moving.
+                // `Subtype`   :Only transmutes the type, so moves.
                 // So it's safe to skip these.
                 ProjectionElem::OpaqueCast(_)
                 | ProjectionElem::Subtype(_)
diff --git a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs
index 594bb9bf142..1cc049d5a22 100644
--- a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs
+++ b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs
@@ -24,24 +24,31 @@ impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> {
         rvalue: &mut Rvalue<'tcx>,
         location: Location,
     ) {
-        let place_ty = place.ty(self.local_decls, self.tcx);
+        let mut place_ty = place.ty(self.local_decls, self.tcx).ty;
         let mut rval_ty = rvalue.ty(self.local_decls, self.tcx);
-        if place_ty.ty != rval_ty {
-            // Not erasing this causes `Free Regions` errors in validator,
-            // when rval is `ReStatic`.
-            rval_ty = self.tcx.erase_regions_ty(rval_ty);
+        // Not erasing this causes `Free Regions` errors in validator,
+        // when rval is `ReStatic`.
+        rval_ty = self.tcx.erase_regions_ty(rval_ty);
+        place_ty = self.tcx.erase_regions(place_ty);
+        if place_ty != rval_ty {
             let temp = self
                 .patcher
                 .new_temp(rval_ty, self.local_decls[place.as_ref().local].source_info.span);
             let new_place = Place::from(temp);
             self.patcher.add_assign(location, new_place, rvalue.clone());
-            let subtyped =
-                new_place.project_deeper(&[ProjectionElem::Subtype(place_ty.ty)], self.tcx);
+            let subtyped = new_place.project_deeper(&[ProjectionElem::Subtype(place_ty)], self.tcx);
             *rvalue = Rvalue::Use(Operand::Move(subtyped));
         }
     }
 }
 
+// Aim here is to do this kind of transformation:
+//
+// let place: place_ty = rval;
+// // gets transformed to
+// let temp: rval_ty = rval;
+// let place: place_ty = temp as place_ty;
+//
 pub fn subtype_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     let patch = MirPatch::new(body);
     let mut checker = SubTypeChecker { tcx, patcher: patch, local_decls: &body.local_decls };
diff --git a/src/tools/stable-mir-dev b/src/tools/stable-mir-dev
deleted file mode 160000
-Subproject 9434648ba82a0519222677bcc3fdf8b4f1ac5ce
diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff
index 1c2077ef5a3..4a816e024c5 100644
--- a/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff
@@ -37,7 +37,7 @@
 -         _4 = g() -> [return: bb1, unwind unreachable];
 +         StorageLive(_5);
 +         _5 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
-+         _4 = move (_5as {generator@$DIR/inline_generator.rs:16:5: 16:8});
++         _4 = move (_5 as subtype {generator@$DIR/inline_generator.rs:16:5: 16:8});
 +         StorageDead(_5);
 +         _3 = &mut _4;
 +         _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}> { pointer: move _3 };
diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
index 689bfcb0a6a..2b910cd6543 100644
--- a/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
@@ -40,7 +40,7 @@
 -     bb1: {
 +         StorageLive(_5);
 +         _5 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
-+         _4 = move (_5as {generator@$DIR/inline_generator.rs:16:5: 16:8});
++         _4 = move (_5 as subtype {generator@$DIR/inline_generator.rs:16:5: 16:8});
 +         StorageDead(_5);
           _3 = &mut _4;
 -         _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new(move _3) -> [return: bb2, unwind: bb5];
diff --git a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir
index e5c9815c780..ec894fa511a 100644
--- a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir
+++ b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-abort.mir
@@ -22,7 +22,6 @@ fn main() -> () {
     let _24: i32;
     let mut _26: *const i32;
     let _27: ();
-    let mut _29: for<'a> fn(&'a i32) -> &'a i32;
     scope 1 {
         debug x => _1;
         let _3: &mut i32;
@@ -106,8 +105,7 @@ fn main() -> () {
         StorageLive(_14);
         _14 = {closure@main::{closure#0}};
         Retag(_14);
-        _29 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Normal)));
-        _13 = move (_29as for<'a> fn(&'a i32) -> &'a i32);
+        _13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Normal)));
         StorageDead(_14);
         StorageLive(_15);
         StorageLive(_16);
diff --git a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
index f08cf6f3d78..d89124f699b 100644
--- a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
+++ b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
@@ -22,7 +22,6 @@ fn main() -> () {
     let _24: i32;
     let mut _26: *const i32;
     let _27: ();
-    let mut _29: for<'a> fn(&'a i32) -> &'a i32;
     scope 1 {
         debug x => _1;
         let _3: &mut i32;
@@ -106,8 +105,7 @@ fn main() -> () {
         StorageLive(_14);
         _14 = {closure@main::{closure#0}};
         Retag(_14);
-        _29 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Normal)));
-        _13 = move (_29as for<'a> fn(&'a i32) -> &'a i32);
+        _13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Normal)));
         StorageDead(_14);
         StorageLive(_15);
         StorageLive(_16);