@@ -1977,8 +1977,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19771977 Rvalue :: Cast ( cast_kind, op, ty) => {
19781978 self . check_operand ( op, location) ;
19791979
1980- match cast_kind {
1981- CastKind :: PointerCoercion ( PointerCoercion :: ReifyFnPointer ) => {
1980+ match * cast_kind {
1981+ CastKind :: PointerCoercion ( PointerCoercion :: ReifyFnPointer , coercion_source) => {
1982+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
19821983 let src_sig = op. ty ( body, tcx) . fn_sig ( tcx) ;
19831984
19841985 // HACK: This shouldn't be necessary... We can remove this when we actually
@@ -2009,15 +2010,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20092010 self . prove_predicate (
20102011 ty:: ClauseKind :: WellFormed ( src_ty. into ( ) ) ,
20112012 location. to_locations ( ) ,
2012- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2013+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
20132014 ) ;
20142015
20152016 let src_ty = self . normalize ( src_ty, location) ;
20162017 if let Err ( terr) = self . sub_types (
20172018 src_ty,
20182019 * ty,
20192020 location. to_locations ( ) ,
2020- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2021+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
20212022 ) {
20222023 span_mirbug ! (
20232024 self ,
@@ -2038,7 +2039,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20382039 self . prove_predicate (
20392040 ty:: ClauseKind :: WellFormed ( src_ty. into ( ) ) ,
20402041 location. to_locations ( ) ,
2041- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2042+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
20422043 ) ;
20432044
20442045 // The type that we see in the fcx is like
@@ -2051,7 +2052,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20512052 src_ty,
20522053 * ty,
20532054 location. to_locations ( ) ,
2054- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2055+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
20552056 ) {
20562057 span_mirbug ! (
20572058 self ,
@@ -2064,19 +2065,23 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20642065 }
20652066 }
20662067
2067- CastKind :: PointerCoercion ( PointerCoercion :: ClosureFnPointer ( safety) ) => {
2068+ CastKind :: PointerCoercion (
2069+ PointerCoercion :: ClosureFnPointer ( safety) ,
2070+ coercion_source,
2071+ ) => {
20682072 let sig = match op. ty ( body, tcx) . kind ( ) {
20692073 ty:: Closure ( _, args) => args. as_closure ( ) . sig ( ) ,
20702074 _ => bug ! ( ) ,
20712075 } ;
20722076 let ty_fn_ptr_from =
2073- Ty :: new_fn_ptr ( tcx, tcx. signature_unclosure ( sig, * safety) ) ;
2077+ Ty :: new_fn_ptr ( tcx, tcx. signature_unclosure ( sig, safety) ) ;
20742078
2079+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
20752080 if let Err ( terr) = self . sub_types (
20762081 ty_fn_ptr_from,
20772082 * ty,
20782083 location. to_locations ( ) ,
2079- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2084+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
20802085 ) {
20812086 span_mirbug ! (
20822087 self ,
@@ -2089,7 +2094,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20892094 }
20902095 }
20912096
2092- CastKind :: PointerCoercion ( PointerCoercion :: UnsafeFnPointer ) => {
2097+ CastKind :: PointerCoercion (
2098+ PointerCoercion :: UnsafeFnPointer ,
2099+ coercion_source,
2100+ ) => {
20932101 let fn_sig = op. ty ( body, tcx) . fn_sig ( tcx) ;
20942102
20952103 // The type that we see in the fcx is like
@@ -2101,11 +2109,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21012109
21022110 let ty_fn_ptr_from = tcx. safe_to_unsafe_fn_ty ( fn_sig) ;
21032111
2112+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
21042113 if let Err ( terr) = self . sub_types (
21052114 ty_fn_ptr_from,
21062115 * ty,
21072116 location. to_locations ( ) ,
2108- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2117+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
21092118 ) {
21102119 span_mirbug ! (
21112120 self ,
@@ -2118,31 +2127,29 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21182127 }
21192128 }
21202129
2121- CastKind :: PointerCoercion ( PointerCoercion :: Unsize ) => {
2130+ CastKind :: PointerCoercion ( PointerCoercion :: Unsize , coercion_source ) => {
21222131 let & ty = ty;
21232132 let trait_ref = ty:: TraitRef :: new (
21242133 tcx,
21252134 tcx. require_lang_item ( LangItem :: CoerceUnsized , Some ( span) ) ,
21262135 [ op. ty ( body, tcx) , ty] ,
21272136 ) ;
21282137
2138+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
2139+ let unsize_to = tcx. fold_regions ( ty, |r, _| {
2140+ if let ty:: ReVar ( _) = r. kind ( ) { tcx. lifetimes . re_erased } else { r }
2141+ } ) ;
21292142 self . prove_trait_ref (
21302143 trait_ref,
21312144 location. to_locations ( ) ,
21322145 ConstraintCategory :: Cast {
2133- is_coercion : true ,
2134- unsize_to : Some ( tcx. fold_regions ( ty, |r, _| {
2135- if let ty:: ReVar ( _) = r. kind ( ) {
2136- tcx. lifetimes . re_erased
2137- } else {
2138- r
2139- }
2140- } ) ) ,
2146+ is_implicit_coercion,
2147+ unsize_to : Some ( unsize_to) ,
21412148 } ,
21422149 ) ;
21432150 }
21442151
2145- CastKind :: PointerCoercion ( PointerCoercion :: DynStar ) => {
2152+ CastKind :: PointerCoercion ( PointerCoercion :: DynStar , coercion_source ) => {
21462153 // get the constraints from the target type (`dyn* Clone`)
21472154 //
21482155 // apply them to prove that the source type `Foo` implements `Clone` etc
@@ -2153,12 +2160,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21532160
21542161 let self_ty = op. ty ( body, tcx) ;
21552162
2163+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
21562164 self . prove_predicates (
21572165 existential_predicates
21582166 . iter ( )
21592167 . map ( |predicate| predicate. with_self_ty ( tcx, self_ty) ) ,
21602168 location. to_locations ( ) ,
2161- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2169+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
21622170 ) ;
21632171
21642172 let outlives_predicate = tcx. mk_predicate ( Binder :: dummy (
@@ -2169,11 +2177,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21692177 self . prove_predicate (
21702178 outlives_predicate,
21712179 location. to_locations ( ) ,
2172- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2180+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
21732181 ) ;
21742182 }
21752183
2176- CastKind :: PointerCoercion ( PointerCoercion :: MutToConstPointer ) => {
2184+ CastKind :: PointerCoercion (
2185+ PointerCoercion :: MutToConstPointer ,
2186+ coercion_source,
2187+ ) => {
21772188 let ty:: RawPtr ( ty_from, hir:: Mutability :: Mut ) = op. ty ( body, tcx) . kind ( )
21782189 else {
21792190 span_mirbug ! ( self , rvalue, "unexpected base type for cast {:?}" , ty, ) ;
@@ -2183,11 +2194,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21832194 span_mirbug ! ( self , rvalue, "unexpected target type for cast {:?}" , ty, ) ;
21842195 return ;
21852196 } ;
2197+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
21862198 if let Err ( terr) = self . sub_types (
21872199 * ty_from,
21882200 * ty_to,
21892201 location. to_locations ( ) ,
2190- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2202+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
21912203 ) {
21922204 span_mirbug ! (
21932205 self ,
@@ -2200,7 +2212,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22002212 }
22012213 }
22022214
2203- CastKind :: PointerCoercion ( PointerCoercion :: ArrayToPointer ) => {
2215+ CastKind :: PointerCoercion ( PointerCoercion :: ArrayToPointer , coercion_source ) => {
22042216 let ty_from = op. ty ( body, tcx) ;
22052217
22062218 let opt_ty_elem_mut = match ty_from. kind ( ) {
@@ -2245,11 +2257,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22452257 return ;
22462258 }
22472259
2260+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
22482261 if let Err ( terr) = self . sub_types (
22492262 * ty_elem,
22502263 * ty_to,
22512264 location. to_locations ( ) ,
2252- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2265+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
22532266 ) {
22542267 span_mirbug ! (
22552268 self ,
@@ -2431,7 +2444,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
24312444 dst_obj,
24322445 location. to_locations ( ) ,
24332446 ConstraintCategory :: Cast {
2434- is_coercion : false ,
2447+ is_implicit_coercion : false ,
24352448 unsize_to : None ,
24362449 } ,
24372450 )
0 commit comments