@@ -1975,8 +1975,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1975
1975
Rvalue :: Cast ( cast_kind, op, ty) => {
1976
1976
self . check_operand ( op, location) ;
1977
1977
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 ;
1980
1981
let src_sig = op. ty ( body, tcx) . fn_sig ( tcx) ;
1981
1982
1982
1983
// HACK: This shouldn't be necessary... We can remove this when we actually
@@ -2007,15 +2008,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2007
2008
self . prove_predicate (
2008
2009
ty:: ClauseKind :: WellFormed ( src_ty. into ( ) ) ,
2009
2010
location. to_locations ( ) ,
2010
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2011
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2011
2012
) ;
2012
2013
2013
2014
let src_ty = self . normalize ( src_ty, location) ;
2014
2015
if let Err ( terr) = self . sub_types (
2015
2016
src_ty,
2016
2017
* ty,
2017
2018
location. to_locations ( ) ,
2018
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2019
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2019
2020
) {
2020
2021
span_mirbug ! (
2021
2022
self ,
@@ -2036,7 +2037,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2036
2037
self . prove_predicate (
2037
2038
ty:: ClauseKind :: WellFormed ( src_ty. into ( ) ) ,
2038
2039
location. to_locations ( ) ,
2039
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2040
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2040
2041
) ;
2041
2042
2042
2043
// The type that we see in the fcx is like
@@ -2049,7 +2050,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2049
2050
src_ty,
2050
2051
* ty,
2051
2052
location. to_locations ( ) ,
2052
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2053
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2053
2054
) {
2054
2055
span_mirbug ! (
2055
2056
self ,
@@ -2062,19 +2063,23 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2062
2063
}
2063
2064
}
2064
2065
2065
- CastKind :: PointerCoercion ( PointerCoercion :: ClosureFnPointer ( safety) ) => {
2066
+ CastKind :: PointerCoercion (
2067
+ PointerCoercion :: ClosureFnPointer ( safety) ,
2068
+ coercion_source,
2069
+ ) => {
2066
2070
let sig = match op. ty ( body, tcx) . kind ( ) {
2067
2071
ty:: Closure ( _, args) => args. as_closure ( ) . sig ( ) ,
2068
2072
_ => bug ! ( ) ,
2069
2073
} ;
2070
2074
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) ) ;
2072
2076
2077
+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
2073
2078
if let Err ( terr) = self . sub_types (
2074
2079
ty_fn_ptr_from,
2075
2080
* ty,
2076
2081
location. to_locations ( ) ,
2077
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2082
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2078
2083
) {
2079
2084
span_mirbug ! (
2080
2085
self ,
@@ -2087,7 +2092,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2087
2092
}
2088
2093
}
2089
2094
2090
- CastKind :: PointerCoercion ( PointerCoercion :: UnsafeFnPointer ) => {
2095
+ CastKind :: PointerCoercion (
2096
+ PointerCoercion :: UnsafeFnPointer ,
2097
+ coercion_source,
2098
+ ) => {
2091
2099
let fn_sig = op. ty ( body, tcx) . fn_sig ( tcx) ;
2092
2100
2093
2101
// The type that we see in the fcx is like
@@ -2099,11 +2107,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2099
2107
2100
2108
let ty_fn_ptr_from = tcx. safe_to_unsafe_fn_ty ( fn_sig) ;
2101
2109
2110
+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
2102
2111
if let Err ( terr) = self . sub_types (
2103
2112
ty_fn_ptr_from,
2104
2113
* ty,
2105
2114
location. to_locations ( ) ,
2106
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2115
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2107
2116
) {
2108
2117
span_mirbug ! (
2109
2118
self ,
@@ -2116,31 +2125,29 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2116
2125
}
2117
2126
}
2118
2127
2119
- CastKind :: PointerCoercion ( PointerCoercion :: Unsize ) => {
2128
+ CastKind :: PointerCoercion ( PointerCoercion :: Unsize , coercion_source ) => {
2120
2129
let & ty = ty;
2121
2130
let trait_ref = ty:: TraitRef :: new (
2122
2131
tcx,
2123
2132
tcx. require_lang_item ( LangItem :: CoerceUnsized , Some ( span) ) ,
2124
2133
[ op. ty ( body, tcx) , ty] ,
2125
2134
) ;
2126
2135
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
+ } ) ;
2127
2140
self . prove_trait_ref (
2128
2141
trait_ref,
2129
2142
location. to_locations ( ) ,
2130
2143
ConstraintCategory :: Cast {
2131
- is_coercion : true ,
2132
- unsize_to : Some ( tcx. fold_regions ( ty, |r, _| {
2133
- if let ty:: ReVar ( _) = r. kind ( ) {
2134
- tcx. lifetimes . re_erased
2135
- } else {
2136
- r
2137
- }
2138
- } ) ) ,
2144
+ is_implicit_coercion,
2145
+ unsize_to : Some ( unsize_to) ,
2139
2146
} ,
2140
2147
) ;
2141
2148
}
2142
2149
2143
- CastKind :: PointerCoercion ( PointerCoercion :: DynStar ) => {
2150
+ CastKind :: PointerCoercion ( PointerCoercion :: DynStar , coercion_source ) => {
2144
2151
// get the constraints from the target type (`dyn* Clone`)
2145
2152
//
2146
2153
// apply them to prove that the source type `Foo` implements `Clone` etc
@@ -2151,12 +2158,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2151
2158
2152
2159
let self_ty = op. ty ( body, tcx) ;
2153
2160
2161
+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
2154
2162
self . prove_predicates (
2155
2163
existential_predicates
2156
2164
. iter ( )
2157
2165
. map ( |predicate| predicate. with_self_ty ( tcx, self_ty) ) ,
2158
2166
location. to_locations ( ) ,
2159
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2167
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2160
2168
) ;
2161
2169
2162
2170
let outlives_predicate = tcx. mk_predicate ( Binder :: dummy (
@@ -2167,11 +2175,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2167
2175
self . prove_predicate (
2168
2176
outlives_predicate,
2169
2177
location. to_locations ( ) ,
2170
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2178
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2171
2179
) ;
2172
2180
}
2173
2181
2174
- CastKind :: PointerCoercion ( PointerCoercion :: MutToConstPointer ) => {
2182
+ CastKind :: PointerCoercion (
2183
+ PointerCoercion :: MutToConstPointer ,
2184
+ coercion_source,
2185
+ ) => {
2175
2186
let ty:: RawPtr ( ty_from, hir:: Mutability :: Mut ) = op. ty ( body, tcx) . kind ( )
2176
2187
else {
2177
2188
span_mirbug ! ( self , rvalue, "unexpected base type for cast {:?}" , ty, ) ;
@@ -2181,11 +2192,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2181
2192
span_mirbug ! ( self , rvalue, "unexpected target type for cast {:?}" , ty, ) ;
2182
2193
return ;
2183
2194
} ;
2195
+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
2184
2196
if let Err ( terr) = self . sub_types (
2185
2197
* ty_from,
2186
2198
* ty_to,
2187
2199
location. to_locations ( ) ,
2188
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2200
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2189
2201
) {
2190
2202
span_mirbug ! (
2191
2203
self ,
@@ -2198,7 +2210,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2198
2210
}
2199
2211
}
2200
2212
2201
- CastKind :: PointerCoercion ( PointerCoercion :: ArrayToPointer ) => {
2213
+ CastKind :: PointerCoercion ( PointerCoercion :: ArrayToPointer , coercion_source ) => {
2202
2214
let ty_from = op. ty ( body, tcx) ;
2203
2215
2204
2216
let opt_ty_elem_mut = match ty_from. kind ( ) {
@@ -2243,11 +2255,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2243
2255
return ;
2244
2256
}
2245
2257
2258
+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
2246
2259
if let Err ( terr) = self . sub_types (
2247
2260
* ty_elem,
2248
2261
* ty_to,
2249
2262
location. to_locations ( ) ,
2250
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2263
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2251
2264
) {
2252
2265
span_mirbug ! (
2253
2266
self ,
@@ -2429,7 +2442,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2429
2442
dst_obj,
2430
2443
location. to_locations ( ) ,
2431
2444
ConstraintCategory :: Cast {
2432
- is_coercion : false ,
2445
+ is_implicit_coercion : false ,
2433
2446
unsize_to : None ,
2434
2447
} ,
2435
2448
)
0 commit comments