Skip to content

Commit 6f0c5ee

Browse files
committed
change is_subtype to relate_types
1 parent cd7f471 commit 6f0c5ee

File tree

15 files changed

+128
-86
lines changed

15 files changed

+128
-86
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -716,14 +716,11 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
716716
}
717717
PlaceTy::from_ty(fty)
718718
}
719-
ProjectionElem::Subtype(_) => {
720-
let guard = span_mirbug_and_err!(
721-
self,
722-
place,
723-
"ProjectionElem::Subtype shouldn't exist in borrowck"
724-
);
725-
PlaceTy::from_ty(Ty::new_error(tcx, guard))
726-
}
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+
)),
727724
ProjectionElem::OpaqueCast(ty) => {
728725
let ty = self.sanitize_type(place, ty);
729726
let ty = self.cx.normalize(ty, location);
@@ -2564,14 +2561,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
25642561
}
25652562
}
25662563
ProjectionElem::Field(..)
2567-
| ProjectionElem::Subtype(..)
25682564
| ProjectionElem::Downcast(..)
25692565
| ProjectionElem::OpaqueCast(..)
25702566
| ProjectionElem::Index(..)
25712567
| ProjectionElem::ConstantIndex { .. }
25722568
| ProjectionElem::Subslice { .. } => {
25732569
// other field access
25742570
}
2571+
ProjectionElem::Subtype(_) => {
2572+
bug!("ProjectionElem::Subtype shouldn't exist in borrowck")
2573+
}
25752574
}
25762575
}
25772576
}

compiler/rustc_codegen_cranelift/src/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -876,7 +876,7 @@ pub(crate) fn codegen_place<'tcx>(
876876
cplace = cplace.place_deref(fx);
877877
}
878878
PlaceElem::OpaqueCast(ty) => bug!("encountered OpaqueCast({ty}) in codegen"),
879-
PlaceElem::Subtype(ty) => cplace = cplace.place_transmute_type(fx, ty),
879+
PlaceElem::Subtype(ty) => cplace = cplace.place_transmute_type(fx, fx.monomorphize(ty)),
880880
PlaceElem::Field(field, _ty) => {
881881
cplace = cplace.place_field(fx, field);
882882
}

compiler/rustc_codegen_cranelift/src/value_and_place.rs

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

677+
/// Used for `ProjectionElem::Subtype`, ty has to be monomorphized before
678+
/// passed on.
677679
pub(crate) fn place_transmute_type(
678680
self,
679681
fx: &mut FunctionCx<'_, '_, 'tcx>,
680682
ty: Ty<'tcx>,
681683
) -> CPlace<'tcx> {
682-
CPlace { inner: self.inner, layout: fx.layout_of(fx.monomorphize(ty)) }
684+
CPlace { inner: self.inner, layout: fx.layout_of(ty) }
683685
}
684686

685687
pub(crate) fn place_field(

compiler/rustc_const_eval/src/interpret/eval_context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_middle::ty::layout::{
1313
self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers,
1414
TyAndLayout,
1515
};
16-
use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable};
16+
use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, Variance};
1717
use rustc_mir_dataflow::storage::always_storage_live_locals;
1818
use rustc_session::Limit;
1919
use rustc_span::Span;
@@ -384,7 +384,7 @@ pub(super) fn mir_assign_valid_types<'tcx>(
384384
// all normal lifetimes are erased, higher-ranked types with their
385385
// late-bound lifetimes are still around and can lead to type
386386
// differences.
387-
if util::is_subtype(tcx, param_env, src.ty, dest.ty) {
387+
if util::relate_types(tcx, param_env, Variance::Covariant, src.ty, dest.ty) {
388388
// Make sure the layout is equal, too -- just to be safe. Miri really
389389
// needs layout equality. For performance reason we skip this check when
390390
// the types are equal. Equal types *can* have different layouts when

compiler/rustc_const_eval/src/transform/validate.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_infer::traits::Reveal;
77
use rustc_middle::mir::interpret::Scalar;
88
use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
99
use rustc_middle::mir::*;
10-
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
10+
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt, Variance};
1111
use rustc_mir_dataflow::impls::MaybeStorageLive;
1212
use rustc_mir_dataflow::storage::always_storage_live_locals;
1313
use rustc_mir_dataflow::{Analysis, ResultsCursor};
@@ -16,7 +16,7 @@ use rustc_target::spec::abi::Abi;
1616

1717
use crate::util::is_within_packed;
1818

19-
use crate::util::is_subtype;
19+
use crate::util::relate_types;
2020

2121
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2222
enum EdgeKind {
@@ -604,7 +604,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
604604
return true;
605605
}
606606

607-
return crate::util::is_subtype(self.tcx, self.param_env, src, dest);
607+
// After borrowck subtyping should be fully explicit via
608+
// `Subtype` projections.
609+
let variance = if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
610+
Variance::Invariant
611+
} else {
612+
Variance::Covariant
613+
};
614+
615+
crate::util::relate_types(self.tcx, self.param_env, variance, src, dest)
608616
}
609617
}
610618

@@ -756,9 +764,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
756764
}
757765
}
758766
ProjectionElem::Subtype(ty) => {
759-
if !is_subtype(
767+
if !relate_types(
760768
self.tcx,
761769
self.param_env,
770+
Variance::Covariant,
762771
ty,
763772
place_ref.ty(&self.body.local_decls, self.tcx).ty,
764773
) {

compiler/rustc_const_eval/src/util/compare_types.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
66
use rustc_infer::infer::TyCtxtInferExt;
77
use rustc_middle::traits::{DefiningAnchor, ObligationCause};
8-
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
8+
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, Variance};
99
use rustc_trait_selection::traits::ObligationCtxt;
1010

1111
/// Returns whether the two types are equal up to subtyping.
@@ -24,16 +24,22 @@ pub fn is_equal_up_to_subtyping<'tcx>(
2424
}
2525

2626
// Check for subtyping in either direction.
27-
is_subtype(tcx, param_env, src, dest) || is_subtype(tcx, param_env, dest, src)
27+
relate_types(tcx, param_env, Variance::Covariant, src, dest)
28+
|| relate_types(tcx, param_env, Variance::Covariant, dest, src)
2829
}
2930

3031
/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
3132
///
33+
/// For almost all of the use cases variance should be `Covariant`,
34+
/// in `MirPhase` >= `MirPhase::Runtime(RuntimePhase::Initial` variance should
35+
/// be `Invariant`.
36+
///
3237
/// This mostly ignores opaque types as it can be used in constraining contexts
3338
/// while still computing the final underlying type.
34-
pub fn is_subtype<'tcx>(
39+
pub fn relate_types<'tcx>(
3540
tcx: TyCtxt<'tcx>,
3641
param_env: ParamEnv<'tcx>,
42+
variance: Variance,
3743
src: Ty<'tcx>,
3844
dest: Ty<'tcx>,
3945
) -> bool {
@@ -48,7 +54,7 @@ pub fn is_subtype<'tcx>(
4854
let cause = ObligationCause::dummy();
4955
let src = ocx.normalize(&cause, param_env, src);
5056
let dest = ocx.normalize(&cause, param_env, dest);
51-
match ocx.sub(&cause, param_env, src, dest) {
57+
match ocx.relate(&cause, param_env, variance, src, dest) {
5258
Ok(()) => {}
5359
Err(_) => return false,
5460
};

compiler/rustc_const_eval/src/util/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mod type_name;
77

88
pub use self::alignment::{is_disaligned, is_within_packed};
99
pub use self::check_validity_requirement::check_validity_requirement;
10-
pub use self::compare_types::{is_equal_up_to_subtyping, is_subtype};
10+
pub use self::compare_types::{is_equal_up_to_subtyping, relate_types};
1111
pub use self::type_name::type_name;
1212

1313
/// Classify whether an operator is "left-homogeneous", i.e., the LHS has the

compiler/rustc_mir_transform/src/inline.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,13 @@ impl<'tcx> Inliner<'tcx> {
218218
// Normally, this shouldn't be required, but trait normalization failure can create a
219219
// validation ICE.
220220
let output_type = callee_body.return_ty();
221-
if !util::is_subtype(self.tcx, self.param_env, output_type, destination_ty) {
221+
if !util::relate_types(
222+
self.tcx,
223+
self.param_env,
224+
ty::Variance::Covariant,
225+
output_type,
226+
destination_ty,
227+
) {
222228
trace!(?output_type, ?destination_ty);
223229
return Err("failed to normalize return type");
224230
}
@@ -248,7 +254,13 @@ impl<'tcx> Inliner<'tcx> {
248254
self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter())
249255
{
250256
let input_type = callee_body.local_decls[input].ty;
251-
if !util::is_subtype(self.tcx, self.param_env, input_type, arg_ty) {
257+
if !util::relate_types(
258+
self.tcx,
259+
self.param_env,
260+
ty::Variance::Covariant,
261+
input_type,
262+
arg_ty,
263+
) {
252264
trace!(?arg_ty, ?input_type);
253265
return Err("failed to normalize tuple argument type");
254266
}
@@ -257,7 +269,13 @@ impl<'tcx> Inliner<'tcx> {
257269
for (arg, input) in args.iter().zip(callee_body.args_iter()) {
258270
let input_type = callee_body.local_decls[input].ty;
259271
let arg_ty = arg.ty(&caller_body.local_decls, self.tcx);
260-
if !util::is_subtype(self.tcx, self.param_env, input_type, arg_ty) {
272+
if !util::relate_types(
273+
self.tcx,
274+
self.param_env,
275+
ty::Variance::Covariant,
276+
input_type,
277+
arg_ty,
278+
) {
261279
trace!(?arg_ty, ?input_type);
262280
return Err("failed to normalize argument type");
263281
}

compiler/rustc_trait_selection/src/traits/engine.rs

+15
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use rustc_middle::traits::query::NoSolution;
2323
use rustc_middle::ty::error::TypeError;
2424
use rustc_middle::ty::ToPredicate;
2525
use rustc_middle::ty::TypeFoldable;
26+
use rustc_middle::ty::Variance;
2627
use rustc_middle::ty::{self, Ty, TyCtxt};
2728
use rustc_session::config::TraitSolver;
2829

@@ -156,6 +157,20 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
156157
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
157158
}
158159

160+
pub fn relate<T: ToTrace<'tcx>>(
161+
&self,
162+
cause: &ObligationCause<'tcx>,
163+
param_env: ty::ParamEnv<'tcx>,
164+
variance: Variance,
165+
expected: T,
166+
actual: T,
167+
) -> Result<(), TypeError<'tcx>> {
168+
self.infcx
169+
.at(cause, param_env)
170+
.relate(DefineOpaqueTypes::Yes, expected, variance, actual)
171+
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
172+
}
173+
159174
/// Checks whether `expected` is a supertype of `actual`: `expected :> actual`.
160175
pub fn sup<T: ToTrace<'tcx>>(
161176
&self,

src/tools/stable-mir-dev

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 9434648ba82a0519222677bcc3fdf8b4f1ac5ced

tabula.rs

-14
This file was deleted.

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

+26-23
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
let mut _2: std::pin::Pin<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>;
88
let mut _3: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
99
let mut _4: {generator@$DIR/inline_generator.rs:16:5: 16:8};
10-
+ let mut _5: bool;
10+
+ let mut _6: bool;
1111
scope 1 {
1212
debug _r => _1;
1313
}
1414
+ scope 2 (inlined g) {
15-
+ let mut _5: [generator@$DIR/inline_generator.rs:16:5: 16:8];
15+
+ let mut _5: {generator@$DIR/inline_generator.rs:16:5: 16:8};
1616
+ }
1717
+ scope 3 (inlined Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new) {
1818
+ debug pointer => _3;
@@ -23,10 +23,10 @@
2323
+ }
2424
+ }
2525
+ scope 6 (inlined g::{closure#0}) {
26-
+ debug a => _5;
27-
+ let mut _6: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
28-
+ let mut _7: u32;
29-
+ let mut _8: i32;
26+
+ debug a => _6;
27+
+ let mut _7: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
28+
+ let mut _8: u32;
29+
+ let mut _9: i32;
3030
+ }
3131

3232
bb0: {
@@ -35,21 +35,24 @@
3535
StorageLive(_3);
3636
StorageLive(_4);
3737
- _4 = g() -> [return: bb1, unwind unreachable];
38-
+ _4 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
38+
+ StorageLive(_5);
39+
+ _5 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
40+
+ _4 = move (_5as {generator@$DIR/inline_generator.rs:16:5: 16:8});
41+
+ StorageDead(_5);
3942
+ _3 = &mut _4;
4043
+ _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}> { pointer: move _3 };
4144
+ StorageDead(_3);
42-
+ StorageLive(_5);
43-
+ _5 = const false;
44-
+ _6 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
45-
+ _7 = discriminant((*_6));
46-
+ switchInt(move _7) -> [0: bb3, 1: bb7, 3: bb8, otherwise: bb9];
45+
+ StorageLive(_6);
46+
+ _6 = const false;
47+
+ _7 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
48+
+ _8 = discriminant((*_7));
49+
+ switchInt(move _8) -> [0: bb3, 1: bb7, 3: bb8, otherwise: bb9];
4750
}
4851

4952
bb1: {
5053
- _3 = &mut _4;
5154
- _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new(move _3) -> [return: bb2, unwind unreachable];
52-
+ StorageDead(_5);
55+
+ StorageDead(_6);
5356
+ StorageDead(_2);
5457
+ drop(_4) -> [return: bb2, unwind unreachable];
5558
}
@@ -66,27 +69,27 @@
6669
bb3: {
6770
- StorageDead(_2);
6871
- drop(_4) -> [return: bb4, unwind unreachable];
69-
+ StorageLive(_8);
70-
+ switchInt(_5) -> [0: bb4, otherwise: bb5];
72+
+ StorageLive(_9);
73+
+ switchInt(_6) -> [0: bb4, otherwise: bb5];
7174
}
7275

7376
bb4: {
7477
- StorageDead(_4);
7578
- _0 = const ();
7679
- StorageDead(_1);
7780
- return;
78-
+ _8 = const 13_i32;
81+
+ _9 = const 13_i32;
7982
+ goto -> bb6;
8083
+ }
8184
+
8285
+ bb5: {
83-
+ _8 = const 7_i32;
86+
+ _9 = const 7_i32;
8487
+ goto -> bb6;
8588
+ }
8689
+
8790
+ bb6: {
88-
+ _1 = GeneratorState::<i32, bool>::Yielded(move _8);
89-
+ discriminant((*_6)) = 3;
91+
+ _1 = GeneratorState::<i32, bool>::Yielded(move _9);
92+
+ discriminant((*_7)) = 3;
9093
+ goto -> bb1;
9194
+ }
9295
+
@@ -95,10 +98,10 @@
9598
+ }
9699
+
97100
+ bb8: {
98-
+ StorageLive(_8);
99-
+ StorageDead(_8);
100-
+ _1 = GeneratorState::<i32, bool>::Complete(_5);
101-
+ discriminant((*_6)) = 1;
101+
+ StorageLive(_9);
102+
+ StorageDead(_9);
103+
+ _1 = GeneratorState::<i32, bool>::Complete(_6);
104+
+ discriminant((*_7)) = 1;
102105
+ goto -> bb1;
103106
+ }
104107
+

0 commit comments

Comments
 (0)