@@ -1975,8 +1975,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19751975 Rvalue :: Cast ( cast_kind, op, ty) => {
19761976 self . check_operand ( op, location) ;
19771977
1978- match cast_kind {
1979- CastKind :: PointerCoercion ( PointerCoercion :: ReifyFnPointer ) => {
1978+ match * cast_kind {
1979+ CastKind :: PointerCoercion ( PointerCoercion :: ReifyFnPointer , coercion_source) => {
1980+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
19801981 let src_sig = op. ty ( body, tcx) . fn_sig ( tcx) ;
19811982
19821983 // HACK: This shouldn't be necessary... We can remove this when we actually
@@ -2007,15 +2008,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20072008 self . prove_predicate (
20082009 ty:: ClauseKind :: WellFormed ( src_ty. into ( ) ) ,
20092010 location. to_locations ( ) ,
2010- ConstraintCategory :: Cast { unsize_to : None } ,
2011+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
20112012 ) ;
20122013
20132014 let src_ty = self . normalize ( src_ty, location) ;
20142015 if let Err ( terr) = self . sub_types (
20152016 src_ty,
20162017 * ty,
20172018 location. to_locations ( ) ,
2018- ConstraintCategory :: Cast { unsize_to : None } ,
2019+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
20192020 ) {
20202021 span_mirbug ! (
20212022 self ,
@@ -2036,7 +2037,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20362037 self . prove_predicate (
20372038 ty:: ClauseKind :: WellFormed ( src_ty. into ( ) ) ,
20382039 location. to_locations ( ) ,
2039- ConstraintCategory :: Cast { unsize_to : None } ,
2040+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
20402041 ) ;
20412042
20422043 // The type that we see in the fcx is like
@@ -2049,7 +2050,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20492050 src_ty,
20502051 * ty,
20512052 location. to_locations ( ) ,
2052- ConstraintCategory :: Cast { unsize_to : None } ,
2053+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
20532054 ) {
20542055 span_mirbug ! (
20552056 self ,
@@ -2062,19 +2063,23 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20622063 }
20632064 }
20642065
2065- CastKind :: PointerCoercion ( PointerCoercion :: ClosureFnPointer ( safety) ) => {
2066+ CastKind :: PointerCoercion (
2067+ PointerCoercion :: ClosureFnPointer ( safety) ,
2068+ coercion_source,
2069+ ) => {
20662070 let sig = match op. ty ( body, tcx) . kind ( ) {
20672071 ty:: Closure ( _, args) => args. as_closure ( ) . sig ( ) ,
20682072 _ => bug ! ( ) ,
20692073 } ;
20702074 let ty_fn_ptr_from =
2071- Ty :: new_fn_ptr ( tcx, tcx. signature_unclosure ( sig, * safety) ) ;
2075+ Ty :: new_fn_ptr ( tcx, tcx. signature_unclosure ( sig, safety) ) ;
20722076
2077+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
20732078 if let Err ( terr) = self . sub_types (
20742079 ty_fn_ptr_from,
20752080 * ty,
20762081 location. to_locations ( ) ,
2077- ConstraintCategory :: Cast { unsize_to : None } ,
2082+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
20782083 ) {
20792084 span_mirbug ! (
20802085 self ,
@@ -2087,7 +2092,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20872092 }
20882093 }
20892094
2090- CastKind :: PointerCoercion ( PointerCoercion :: UnsafeFnPointer ) => {
2095+ CastKind :: PointerCoercion (
2096+ PointerCoercion :: UnsafeFnPointer ,
2097+ coercion_source,
2098+ ) => {
20912099 let fn_sig = op. ty ( body, tcx) . fn_sig ( tcx) ;
20922100
20932101 // The type that we see in the fcx is like
@@ -2099,11 +2107,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20992107
21002108 let ty_fn_ptr_from = tcx. safe_to_unsafe_fn_ty ( fn_sig) ;
21012109
2110+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
21022111 if let Err ( terr) = self . sub_types (
21032112 ty_fn_ptr_from,
21042113 * ty,
21052114 location. to_locations ( ) ,
2106- ConstraintCategory :: Cast { unsize_to : None } ,
2115+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
21072116 ) {
21082117 span_mirbug ! (
21092118 self ,
@@ -2116,30 +2125,29 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21162125 }
21172126 }
21182127
2119- CastKind :: PointerCoercion ( PointerCoercion :: Unsize ) => {
2128+ CastKind :: PointerCoercion ( PointerCoercion :: Unsize , coercion_source ) => {
21202129 let & ty = ty;
21212130 let trait_ref = ty:: TraitRef :: new (
21222131 tcx,
21232132 tcx. require_lang_item ( LangItem :: CoerceUnsized , Some ( span) ) ,
21242133 [ op. ty ( body, tcx) , ty] ,
21252134 ) ;
21262135
2136+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
2137+ let unsize_to = tcx. fold_regions ( ty, |r, _| {
2138+ if let ty:: ReVar ( _) = r. kind ( ) { tcx. lifetimes . re_erased } else { r }
2139+ } ) ;
21272140 self . prove_trait_ref (
21282141 trait_ref,
21292142 location. to_locations ( ) ,
21302143 ConstraintCategory :: Cast {
2131- unsize_to : Some ( tcx. fold_regions ( ty, |r, _| {
2132- if let ty:: ReVar ( _) = r. kind ( ) {
2133- tcx. lifetimes . re_erased
2134- } else {
2135- r
2136- }
2137- } ) ) ,
2144+ is_implicit_coercion,
2145+ unsize_to : Some ( unsize_to) ,
21382146 } ,
21392147 ) ;
21402148 }
21412149
2142- CastKind :: DynStar => {
2150+ CastKind :: PointerCoercion ( PointerCoercion :: DynStar , coercion_source ) => {
21432151 // get the constraints from the target type (`dyn* Clone`)
21442152 //
21452153 // apply them to prove that the source type `Foo` implements `Clone` etc
@@ -2150,12 +2158,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21502158
21512159 let self_ty = op. ty ( body, tcx) ;
21522160
2161+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
21532162 self . prove_predicates (
21542163 existential_predicates
21552164 . iter ( )
21562165 . map ( |predicate| predicate. with_self_ty ( tcx, self_ty) ) ,
21572166 location. to_locations ( ) ,
2158- ConstraintCategory :: Cast { unsize_to : None } ,
2167+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
21592168 ) ;
21602169
21612170 let outlives_predicate = tcx. mk_predicate ( Binder :: dummy (
@@ -2166,11 +2175,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21662175 self . prove_predicate (
21672176 outlives_predicate,
21682177 location. to_locations ( ) ,
2169- ConstraintCategory :: Cast { unsize_to : None } ,
2178+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
21702179 ) ;
21712180 }
21722181
2173- CastKind :: PointerCoercion ( PointerCoercion :: MutToConstPointer ) => {
2182+ CastKind :: PointerCoercion (
2183+ PointerCoercion :: MutToConstPointer ,
2184+ coercion_source,
2185+ ) => {
21742186 let ty:: RawPtr ( ty_from, hir:: Mutability :: Mut ) = op. ty ( body, tcx) . kind ( )
21752187 else {
21762188 span_mirbug ! ( self , rvalue, "unexpected base type for cast {:?}" , ty, ) ;
@@ -2180,11 +2192,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21802192 span_mirbug ! ( self , rvalue, "unexpected target type for cast {:?}" , ty, ) ;
21812193 return ;
21822194 } ;
2195+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
21832196 if let Err ( terr) = self . sub_types (
21842197 * ty_from,
21852198 * ty_to,
21862199 location. to_locations ( ) ,
2187- ConstraintCategory :: Cast { unsize_to : None } ,
2200+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
21882201 ) {
21892202 span_mirbug ! (
21902203 self ,
@@ -2197,7 +2210,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21972210 }
21982211 }
21992212
2200- CastKind :: PointerCoercion ( PointerCoercion :: ArrayToPointer ) => {
2213+ CastKind :: PointerCoercion ( PointerCoercion :: ArrayToPointer , coercion_source ) => {
22012214 let ty_from = op. ty ( body, tcx) ;
22022215
22032216 let opt_ty_elem_mut = match ty_from. kind ( ) {
@@ -2242,11 +2255,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22422255 return ;
22432256 }
22442257
2258+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
22452259 if let Err ( terr) = self . sub_types (
22462260 * ty_elem,
22472261 * ty_to,
22482262 location. to_locations ( ) ,
2249- ConstraintCategory :: Cast { unsize_to : None } ,
2263+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
22502264 ) {
22512265 span_mirbug ! (
22522266 self ,
@@ -2427,7 +2441,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
24272441 src_obj,
24282442 dst_obj,
24292443 location. to_locations ( ) ,
2430- ConstraintCategory :: Cast { unsize_to : None } ,
2444+ ConstraintCategory :: Cast {
2445+ is_implicit_coercion : false ,
2446+ unsize_to : None ,
2447+ } ,
24312448 )
24322449 . unwrap ( ) ;
24332450 }
0 commit comments