about summary refs log tree commit diff
path: root/compiler/rustc_borrowck/src
diff options
context:
space:
mode:
authorEric Holk <ericholk@microsoft.com>2022-06-28 14:02:30 -0700
committerEric Holk <ericholk@microsoft.com>2022-09-12 16:55:56 -0700
commit549c105bb365e14cb132b29a94126715158c5cfa (patch)
tree3d91612e22e9af455678f03f795f50d1e928ec16 /compiler/rustc_borrowck/src
parent7fccac3ea0db7cbbb1b84ff4ab824f8d85f415fe (diff)
downloadrust-549c105bb365e14cb132b29a94126715158c5cfa.tar.gz
rust-549c105bb365e14cb132b29a94126715158c5cfa.zip
dyn* through more typechecking and MIR
Diffstat (limited to 'compiler/rustc_borrowck/src')
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs37
1 files changed, 35 insertions, 2 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index fc0e95f30c9..c78f9282e30 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -30,8 +30,9 @@ use rustc_middle::ty::cast::CastTy;
 use rustc_middle::ty::subst::{GenericArgKind, SubstsRef, UserSubsts};
 use rustc_middle::ty::visit::TypeVisitable;
 use rustc_middle::ty::{
-    self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, OpaqueHiddenType,
-    OpaqueTypeKey, RegionVid, ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
+    self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic,
+    OpaqueHiddenType, OpaqueTypeKey, RegionVid, ToPredicate, TraitObjectRepresentation, Ty, TyCtxt,
+    UserType, UserTypeAnnotationIndex,
 };
 use rustc_span::def_id::CRATE_DEF_ID;
 use rustc_span::{Span, DUMMY_SP};
@@ -2009,6 +2010,38 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         );
                     }
 
+                    CastKind::DynStar => {
+                        // get the constraints from the target type (`dyn* Clone`)
+                        //
+                        // apply them to prove that the source type `Foo` implements `Clone` etc
+                        let (existential_predicates, region) = match ty.kind() {
+                            Dynamic(predicates, region, TraitObjectRepresentation::Sized) => {
+                                (predicates, region)
+                            }
+                            _ => panic!("Invalid dyn* cast_ty"),
+                        };
+
+                        let self_ty = op.ty(body, tcx);
+
+                        self.prove_predicates(
+                            existential_predicates
+                                .iter()
+                                .map(|predicate| predicate.with_self_ty(tcx, self_ty)),
+                            location.to_locations(),
+                            ConstraintCategory::Cast,
+                        );
+
+                        let outlives_predicate =
+                            tcx.mk_predicate(Binder::dummy(ty::PredicateKind::TypeOutlives(
+                                ty::OutlivesPredicate(self_ty, *region),
+                            )));
+                        self.prove_predicate(
+                            outlives_predicate,
+                            location.to_locations(),
+                            ConstraintCategory::Cast,
+                        );
+                    }
+
                     CastKind::Pointer(PointerCast::MutToConstPointer) => {
                         let ty::RawPtr(ty::TypeAndMut {
                             ty: ty_from,